<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>The Brown PLT Blog</title>
 <link href="http://blog.brownplt.org/feed/" rel="self"/>
 <link href="http://blog.brownplt.org/"/>
 <updated>2026-02-13T07:44:59+00:00</updated>
 <id>http://blog.brownplt.org/</id>
 <author>
   <name>Brown PLT</name>
   <email>joe@cs.brown.edu</email>
 </author>

 
 <entry>
   <title>LLMs ⭢ Regular Expressions, Responsibly!</title>
   <link href="http://blog.brownplt.org/2025/12/11/pick-regex.html"/>
   <updated>2025-12-11T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2025/12/11/pick-regex</id>
   <content type="html">&lt;p&gt;Do you use GenAI/LLMs to generate your regular expressions? We certainly do! But we always do it with trepidation, given the many slips that can occur with blindly pasting the output into a program. We may have been unclear in our prose, our prose may have been ambiguous, the domain may lend itself to ambiguity (what is a “date”?), the LLM may have misinterpreted what you said, the domain may have &lt;a href=&quot;/2024/07/07/little-tricky-logics-2.html&quot;&gt;persistent misconceptions&lt;/a&gt;, and so on.&lt;/p&gt;

&lt;p&gt;Oh, you &lt;em&gt;read&lt;/em&gt; your regexes, you say? Is this a valid regex for dates?&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;^(?:(?:31-(?:0[13578]|1[02])-(?:\d{4}))|
   (?:29|30-(?:0[13-9]|1[0-2])-(?:\d{4}))|
   (?:29-02-(?:(?:\d\d(?:0[48]|[2468][048]|[13579][26]))|
              (?:[048]000)))|
   (?:0[1-9]|1\d|2[0-8]-(?:0[1-9]|1[0-2])-(?:\d{4})))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But we can do a lot better! Our new tool, PICK:Regex, does the following. It asks you for a prompt and sends it to a GenAI system. However, it doesn’t ask for &lt;em&gt;one&lt;/em&gt; regex; instead, it uses an LLMs ability to interpret prose in multiple ways to generate &lt;em&gt;multiple&lt;/em&gt; (about four) candidate expressions. (The details don’t matter, but if you want to you can open the images below in a new tab to read them more easily.)&lt;/p&gt;

&lt;style&gt;
   figure {
      display: block;
      margin: 20px auto;
      padding: 0;
      max-width: 95%;
   }

   figure img {
      width: 100%;
      height: auto;
   }
&lt;/style&gt;

&lt;figure&gt;
    &lt;img src=&quot;/img/pick/pick-candidates.jpeg&quot; alt=&quot;Screenshot of the PICK tool, with multiple REGEX candidates for dates, including YYYY-MM-DD format and semi-textual (e.g. 1 January 2025)&quot; /&gt;
&lt;/figure&gt;

&lt;p&gt;In theory, that’s better than getting just one interpretation. But now you may have to read four regexes like the above, which is actually worse! Therefore, instead, PICK shows you &lt;em&gt;concrete examples&lt;/em&gt;. Furthermore, the examples are carefully chosen to &lt;em&gt;tell apart the regexes&lt;/em&gt;. You are then asked to upvote/downvote each example. As you do, you are actually voting on all the candidate regexes.&lt;/p&gt;

&lt;figure&gt;
    &lt;img src=&quot;/img/pick/pick-voting.png&quot; alt=&quot;Screenshot of the PICK tool showing the voting process&quot; /&gt;
&lt;/figure&gt;

&lt;p&gt;You can stop at any point (you’re always shown the regexes), but the process naturally halts when only one regex remains (this is your best candidate of the ones you’ve seen so far) or &lt;em&gt;none&lt;/em&gt; remain (in which case it would have been dangerous to use the LLMs output!).&lt;/p&gt;

&lt;p&gt;As you’re looking at examples, you may realize you could have provided a better prompt (or could have used a more expensive LLM). You don’t need to start over; you can &lt;em&gt;revise&lt;/em&gt; your request. This generates regexes afresh, but critically, you don’t lose your hard work: your prior upvotes and downvotes are automatically applied to the new proposed regexes.&lt;/p&gt;

&lt;p&gt;Also as you’re looking at examples, you might come up with some good ones of your own. You can type these into PICK and vote on them (i.e., provide both positive and negative examples), and PICK will add them to the example stream. Similarly, you can edit an example PICK has shown you before voting on it.&lt;/p&gt;

&lt;p&gt;Finally, you can also change your mind. PICK shows you all your prior classifications at the bottom. If you change how you classified an example, that will update the scores of all the candidates.&lt;/p&gt;

&lt;p&gt;PICK is based on the confluence of two very different bodies of ideas. It draws from cognitive science: the idea of understanding the abstract through the concrete, and the theory of contrasting cases. It also puts to work all the formal language closure properties you studied in a theory of computation class and wondered why and when they would ever be useful.&lt;/p&gt;

&lt;p&gt;Enough prose! Please try PICK for yourself. It’s available as an extension from the Visual Studio Code Marketplace (it uses your VSCode LLM configuration). Visit &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=SiddharthaPrasad.pick-regex&quot;&gt;this link&lt;/a&gt;, or search for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SiddharthaPrasad.pick-regex&lt;/code&gt; in the Marketplace. If you don’t have a ready question, try a prompt like “countries of North America”—but before you do, what regex are you expecting? Think about it for a moment, then see what PICK offers you. Let us know what you think!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Sharing is Scaring: Why is Cloud File-Sharing Hard?</title>
   <link href="http://blog.brownplt.org/2025/08/25/cloud-sharing.html"/>
   <updated>2025-08-25T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2025/08/25/cloud-sharing</id>
   <content type="html">&lt;p&gt;Here is an actual situation we were asked to help non-technical
computer users with:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Alice and Bob want to collaborate on a flyer for a social
event. They are more comfortable with Word than with cloud-based tools
like Google Docs. They have both heard that Dropbox is a good way to
share and jointly edit files.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Alice thus creates a draft of the flyer &lt;em&gt;F&lt;/em&gt; on Dropbox. She then
shares &lt;em&gt;F&lt;/em&gt; with Bob. Bob makes a change using Word and informs Alice
he has done so. Alice opens &lt;em&gt;F&lt;/em&gt; and sees no change. Bob confirms he is
editing a file that is in Dropbox.  They have several baffling rounds
of exchange.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Do you see the problem? No? Here’s the critical question: How did
Alice &lt;em&gt;share&lt;/em&gt; &lt;em&gt;F&lt;/em&gt;? Alice dragged the file from the Folder interface into
Google Mail. (Do you see it now?)&lt;/p&gt;

&lt;p&gt;The problem is that “sharing” means at least two very different things: providing a link to a single shared resource, or making a copy of the resource. Each one is correct for some contexts and wrong for others.&lt;/p&gt;

&lt;p&gt;Does this sound familiar? To us, it certainly is! It’s the &lt;em&gt;same&lt;/em&gt; kind of problem we saw when studying &lt;em&gt;programming&lt;/em&gt; misconceptions, work that we have
&lt;a href=&quot;/2024/04/12/behavior-misconceptions.html&quot;&gt;studied in great detail&lt;/a&gt; as part of our work on SMoL and the SMoL Tutor. Indeed, in this work, we call this the &lt;strong&gt;central analogy&lt;/strong&gt;: the deep semantic similarity between&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;sharing document links ↔ aliasing,&lt;/li&gt;
  &lt;li&gt;downloading or attaching documents ↔ copying objects, and&lt;/li&gt;
  &lt;li&gt;editing documents ↔ mutation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We therefore find it especially unsurprising that when you combine mutation with sharing, people get confused. (Of course, there may be a deeper problem: that people are just not very good at reasoning about sharing and mutation. Cloud file-sharing and programming may just be two concrete instantiations of that abstract difficulty, and the same problems may arise in other domains as well.) Essentially, cloud file-sharing operations form an &lt;em&gt;end-user&lt;/em&gt; instruction set architecture (EUISA) over which users “program” to achieve their goals.&lt;/p&gt;

&lt;p&gt;This paper builds on this idea in the following ways:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We identify this analogy both in the abstract and through several concrete examples (drawn from personal experience).&lt;/li&gt;
  &lt;li&gt;We use our knowledge of programming semantics misconceptions to design &lt;em&gt;corresponding&lt;/em&gt; cloud file-sharing situations, and show that people are confused there also.&lt;/li&gt;
  &lt;li&gt;Drawing on the computing education literature, we devise an interesting way to get crowdsourcing subjects to not only “trace” but also “program” over the EUISA, and show that difficulties extend to both situations.&lt;/li&gt;
  &lt;li&gt;We present a formal semantics for cloud file-sharing.&lt;/li&gt;
  &lt;li&gt;We then discuss how this formal semantics might be employed to help end-users.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more details, see &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/akf-sharing-scaring/&quot;&gt;our paper&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;As a fun aside: The formal model is built using &lt;a href=&quot;/2024/04/21/forge.html&quot;&gt;Forge&lt;/a&gt;. We were going to build a custom visualization but, to get a quick prototype in place, we used
&lt;a href=&quot;/2025/06/09/copeanddrag.html&quot;&gt;Cope and Drag&lt;/a&gt;. But the CnD spec was so good that we never needed to build that custom visualization!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Practical Static Analysis for Privacy Bugs</title>
   <link href="http://blog.brownplt.org/2025/08/03/paralegal.html"/>
   <updated>2025-08-03T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2025/08/03/paralegal</id>
   <content type="html">&lt;p&gt;Privacy bugs are deeply problematic for software users (“once it’s out there you can’t take it back”), legally significant (due to laws like the GDPR), and difficult for programmers to find and to keep out. Static program analysis would therefore appear to be very helpful here.&lt;/p&gt;

&lt;p&gt;Unfortunately, making an effective tool runs into several problems:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Rules need to be expressed in a way that is auditable by legal and policy experts, which means they cannot be too close to the level of code.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Policies need to then be mapped to the actual code.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The analysis needs to be as precise as possible.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The analysis needs to also be as quick as possible—ideally, fast enough to integrate into interactive development.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our new system, Paralegal, checks off all these boxes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It supports policies expressed in a first-order logic, but written in a stylized English form. For instance, here is a policy stating that there is a way for all personal data to be deleted:
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Somewhere:
1. For each &quot;user data&quot; type marked user_data:
A. There is a &quot;source&quot; that produces &quot;user data&quot; where:
  a. There is a &quot;deleter&quot; marked deletes where:
    i) &quot;source&quot; goes to &quot;deleter&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;It introduces &lt;em&gt;markers&lt;/em&gt; as a key abstraction for mapping the policy onto the program. Several of the terms above — e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;user_data&lt;/code&gt; — are designated in a lightweight way in the source program:
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#[paralegal::marker(user_data)]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;It deeply leverages Rust’s type system to obtain useful summaries of function behavior without having to traverse their bodies. In particular, this avoids the pain of writing mock versions of functions, which are time-consuming and error-prone, without sacrificing correctness or precision. It also has some additional optimizations, such as adaptive approximation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a result, Paralegal is able to efficiently and effectively analyze several third-party, real-world codebases.&lt;/p&gt;

&lt;p&gt;For more details, see &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/azzr--paralegal/&quot;&gt;our paper&lt;/a&gt;!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Lightweight Diagramming for Lightweight Formal Methods</title>
   <link href="http://blog.brownplt.org/2025/06/09/copeanddrag.html"/>
   <updated>2025-06-09T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2025/06/09/copeanddrag</id>
   <content type="html">&lt;p&gt;Formal methods tools like &lt;a href=&quot;https://alloytools.org/&quot;&gt;Alloy&lt;/a&gt; and &lt;a href=&quot;https://forge-fm.org/&quot;&gt;Forge&lt;/a&gt; help users define, explore, verify, and diagnose specifications for complex systems incrementally. A crucial feature of these tools is their visualizer, which lets users explore generated models through graphical representations.&lt;/p&gt;

&lt;style&gt;

   figure {
      display: block;
      margin: 0;
      padding: 0;
      max-width: 99%;
   }

   figure img {
      width: 100%;
      height: auto;
   }

   figcaption {
      font-family: Arial, sans-serif;
      font-size: 14px;
      color: black;
      margin-top: 10px;
      padding: 5px;
      font-style: italic;
   }
&lt;/style&gt;

&lt;p&gt;In some cases, they suffer from familiar usability issues—such as overlapping lines, unclear labels, or cluttered layouts—that make it hard to understand what the model represents. But even when the diagrams are clean and well-organized, they can still be confusing if the layout doesn’t reflect the structure &lt;strong&gt;that users expect&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, a visualization of a binary tree might place left and right children arbitrarily, rather than arranging them to the left and right of their parent node.  This breaks with common conventions and can make it harder for users to quickly recognize familiar structures. Similarly, if a model is meant to convey a specific organization (e.g., the grouping of files in a directory) but the visualization fails to reflect this, it becomes difficult to discern the intended relationships, making the model harder to interpret and reason about.&lt;/p&gt;

&lt;figure&gt;
    &lt;img src=&quot;https://blog.brownplt.org/img/copeanddrag/sterling-btree.png&quot; alt=&quot;Default Forge visualization of a binary tree with 10 nodes. A node’s left and right children are not consistently laid out to its left and right.&quot; /&gt;
    &lt;figcaption&gt; Fig 1. Default Forge visualization of a binary tree with 10 nodes. A node’s left and right children are not consistently laid out to its left and right.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
    &lt;img src=&quot;https://blog.brownplt.org/img/copeanddrag/filesystem-asv.png&quot; alt=&quot;Alloy visualization of a file system model. Aside from the overlapping edges, the layout fails to convey relationships between entries that share a directory.&quot; /&gt;
    &lt;figcaption&gt;
        Fig 2. Alloy visualization of a &lt;a href=&quot;https://github.com/AlloyTools/models/tree/master/models/file-system&quot;&gt;file system model&lt;/a&gt;. Aside from the overlapping edges, the layout fails to convey relationships between entries that share a directory.
    &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Our &lt;a href=&quot;https://blog.brownplt.org/2024/04/21/forge.html&quot;&gt;previous research&lt;/a&gt; has explored using custom, domain-specific visualizations to address this challenge. Yet existing tools for custom visualization come with several significant drawbacks:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Users must learn and use entirely different languages to create custom visualizations, learning skills (like CSS) that have nothing to do with formal modeling.&lt;/li&gt;
  &lt;li&gt;The level of detail required by these languages (such as controlling how elements are rendered) often makes the visualizer code larger and more complex than the models themselves.&lt;/li&gt;
  &lt;li&gt;Most critically, these visualizations can be brittle. While careful visualization design can handle certain edge cases, they are inherently limited by their authors’ assumptions about potential issues. The very “unknown unknowns” that lightweight formal methods exist to help surface are often masked by visualizers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We encountered this issue even when building visualizations for relatively simple data structures that we understand well. It is well-documented that experts suffer from blind spots about what mistakes students might make. When faced with such a modeling mistake, failing to specify that a node’s left and right children must be distinct, our &lt;a href=&quot;https://github.com/tnelson/Forge/tree/main/forge/examples/bst&quot;&gt;custom visualizer&lt;/a&gt; failed silently.&lt;/p&gt;

&lt;figure style=&quot;display: flex; flex-direction: column; align-items: center;&quot;&gt;
  &lt;div style=&quot;display: flex; gap: 1em; justify-content: center;&quot;&gt;
    &lt;img src=&quot;https://blog.brownplt.org/img/copeanddrag/bt-dag.png&quot; alt=&quot;DAG where the Node -1&apos;s left and right children are both the Node -2.&quot; style=&quot;max-width: 48%; height: auto;&quot; /&gt;
    &lt;img src=&quot;https://blog.brownplt.org/img/copeanddrag/bt-custom-viz.png&quot; alt=&quot;A binary tree where Node -1 has two distinct children, each with value -2.&quot; style=&quot;max-width: 48%; height: auto;&quot; /&gt;
  &lt;/div&gt;
  &lt;figcaption style=&quot;margin-top: 10px; font-style: italic;&quot;&gt;
    Fig 3. The custom visualizer fails to guard against instances that are DAGs, leading to graphs that actually have the same left and right child (left) being rendered as as a trees (right).
  &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Such failures aren’t merely aesthetic—they actively prevent users from discovering a specification error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cope and Drag&lt;/strong&gt; (or CnD) is a novel lightweight diagramming language built to address these issues. CnD’s design was driven by two approaches:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;A top-down exploration of cognitive science principles that influence spatial reasoning, visualization, and diagramming.&lt;/li&gt;
  &lt;li&gt;A bottom-up analysis that distills patterns from dozens of actual custom visualizations.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The resulting language is small, requires minimal annotation, and can be used incrementally. The key idea is that each CnD operation meaningfully refines the default visualization. These operations include &lt;em&gt;constraining&lt;/em&gt; spatial layout (such as positioning child nodes below their parents in a binary tree), &lt;em&gt;grouping&lt;/em&gt; elements (like clustering related components in a software architecture), and &lt;em&gt;directing&lt;/em&gt; drawing style (for instance, coloring nodes in a red-black tree based on their color).&lt;/p&gt;

&lt;figure&gt;
    &lt;img src=&quot;https://blog.brownplt.org/img/copeanddrag/btree-cnd.png&quot; alt=&quot;CnD visualization of the same 10 Node binary tree. A node’s left and right children are consistently laid out to its left and right.&quot; /&gt;
    &lt;figcaption&gt; Fig 4. CnD visualization of the 10 Node binary tree in Fig 1.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
    &lt;img src=&quot;https://blog.brownplt.org/img/copeanddrag/filesystem-cnd.png&quot; alt=&quot;CnD visualization of the same file system model. Grouping conveys how files are related.&quot; /&gt;
    &lt;figcaption&gt;
      Fig 5. CnD visualization of the file system model in Fig 2.
    &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Rather than prioritizing aesthetics, CnD focuses on encoding the spatial intuitions implicit in communicating the model. Its lightweight, declarative structure captures these relationships directly.&lt;/p&gt;

&lt;figure&gt;
    &lt;img src=&quot;https://blog.brownplt.org/img/copeanddrag/face.png&quot; alt=&quot;This figure shows how to incrementally refine default Forge output of an instance describing a face using (A) grouping, (B) orientation, and (C) icons.&quot; /&gt;
    &lt;figcaption&gt; Fig 6. This figure shows how to incrementally refine default Forge output of an instance describing a face using (A) grouping, (B) orientation, and (C) icons. &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Lightweight Specs, Not Programs:&lt;/strong&gt; Diagramming with CnD resembles writing a spec, not coding a full program. An empty spec yields a default diagram; each constraint refines it. Unlike traditional viz tools like D3 (where you don’t get a visualization until you’ve written a full program) CnD supports incremental visualization, making it easy to start and evolve alongside your model.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Useful, not pretty:&lt;/strong&gt; Generated diagrams may lack the visual polish of more sophisticated tools, but they prioritize structural clarity and correctness over style.The trade-off is a lower ceiling: user’s have less fine-grained control over how diagram elements are rendered (e.g., spacing, fonts, shapes).&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Fail Loudly:&lt;/strong&gt; CnD constraints are &lt;em&gt;hard&lt;/em&gt; constraints. When a diagram fails to match the model, the system prevents visualization and produces a solver-generated error.&lt;/p&gt;

    &lt;p&gt;For instance, &lt;a href=&quot;https://www.siddharthaprasad.com/copeanddrag/examples/#bt&quot;&gt;a CnD specification for a binary tree&lt;/a&gt; might encode tree layouts as two constraints (lay the left child below and to the left of its parent, and the right child below and to the right of the parent). When faced with the DAG described earlier, CnD identifies that these visualization constraints are unsatisfiable, and produces an error message instead of a misleading diagram.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
    &lt;img src=&quot;https://blog.brownplt.org/img/copeanddrag/cndfailure.png&quot; alt=&quot;When faced with the DAG described earlier, CnD identifies that these visualization constraints are unsatisfiable, and produces an error message instead of a misleading diagram.&quot; /&gt;
    &lt;figcaption&gt;
      Fig 7. When visualization constraints are unsatisfiable, CnD produces an error message instead of a diagram.
    &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;CnD isn’t the final word on diagramming. It’s one design point in a larger landscape, trading visual polish for ease of use, structural clarity, and exploration of model-diagram mismatches. Other tools will (and should) explore different trade-offs.&lt;/p&gt;

&lt;p&gt;CnD is embedded in an &lt;a href=&quot;https://www.siddharthaprasad.com/copeanddrag/&quot;&gt;open-source&lt;/a&gt; visualizer for Forge. We encourage you to try it as part of your existing Forge workflows. To learn more about CnD, please &lt;a href=&quot;https://www.siddharthaprasad.com/unpublished/pgnk-lightweight-diagramming.pdf&quot;&gt;read our paper&lt;/a&gt;!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Argus: Interactively Debugging Rust trait Errors</title>
   <link href="http://blog.brownplt.org/2025/04/29/argus.html"/>
   <updated>2025-04-29T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2025/04/29/argus</id>
   <content type="html">&lt;p&gt;Traits are a source of bewildering error messages in the Rust community and people have spent money and time trying to improve the resulting diagnostics. We took a different approach. We analyzed a community suite of difficult-to-debug trait errors and formed hypotheses about why they were difficult for engineers to debug. Then, we built an interactive debugger that developers can use in the IDE to debug trait errors. Find more details about our process, the tool, and our paper in our Cognitive Engineering Lab &lt;a href=&quot;https://cel.cs.brown.edu/blog/an-interactive-debugger-for-rust-trait-errors&quot;&gt;blog post&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>LTL Tutor</title>
   <link href="http://blog.brownplt.org/2024/08/08/ltltutor.html"/>
   <updated>2024-08-08T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2024/08/08/ltltutor</id>
   <content type="html">&lt;p&gt;We have been engaged in a multi-year project to improve education in Linear Temporal Logic (LTL) [&lt;a href=&quot;/2022/11/05/little-tricky-logics.html&quot;&gt;Blog Post 1&lt;/a&gt;, &lt;a href=&quot;/2024/07/07/little-tricky-logics-2.html&quot;&gt;Blog Post 2&lt;/a&gt;]. In particular, we have arrived at a detailed understanding of typical misconceptions that learners and even experts have. Our useful outcome from our studies is a set of instruments (think “quizzes”) that instructors can deploy in their classes to understand how well their students understand the logic and what weaknesses they have.&lt;/p&gt;

&lt;p&gt;However, as educators, we recognize that it isn’t always easy to add new materials to classes. Furthermore, your students make certain mistakes—now what? They need explanations of what went wrong, need additional drill problems, and need checks whether they got the additional ones right. It’s hard for an educator to make time for all that. And if one is an independent learner, they don’t even have access to such educators.&lt;/p&gt;

&lt;p&gt;Recognizing these practical difficulties, we have distilled our group’s expertise in LTL into a free online tutor:&lt;/p&gt;

&lt;div style=&quot;text-align: center;&quot;&gt;
  &lt;a href=&quot;https://ltl-tutor.xyz&quot;&gt;https://ltl-tutor.xyz&lt;/a&gt;
&lt;/div&gt;

&lt;style&gt;

   figure {
      display: block;
      margin: 0;
      padding: 0;
      max-width: 99%;
   }

   figure img {
      width: 100%;
      height: auto;
   }

   figcaption {
      font-family: Arial, sans-serif;
      font-size: 14px;
      color: black;
      margin-top: 10px;
      padding: 5px;
      font-style: italic;
   }
&lt;/style&gt;

&lt;p&gt;We have leveraged insights from our studies to create a tool designed to be used by learners with minimal prior instruction.  All you need is a brief introduction to LTL (or even just propositional logic) to get started. As an instructor, you can deliver your usual lecture on the topic (using your preferred framing), and then have your students use the tool to grow and to reinforce their learning.&lt;/p&gt;

&lt;p&gt;In contrast to traditional tutoring systems, which are often tied to a specific curriculum or course, our tutor adaptively generates multiple-choice question-sets in the context of common LTL misconceptions.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The tutor provides students who get a question wrong with &lt;strong&gt;feedback&lt;/strong&gt; in terms of their answer’s relationship to the correct answer. Feedback can take the form of visual metaphors, counterexamples, or an interactive trace-stepper that shows the evaluation of an LTL formula across time.&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
    &lt;img src=&quot;https://blog.brownplt.org/img/ltl-tutor-diagram-feedback.png&quot; alt=&quot;In this example of LTL tutor feedback, a diagram is used to show students that their answer is logically more permissive than the correct answer to the question. The learner is also shown an example of an LTL trace that satisfies their answer but not the correct answer.&quot; /&gt;
    &lt;figcaption&gt; In this example of LTL tutor feedback, a diagram is used to show students that their answer is logically more permissive than the correct answer to the question. The learner is also shown an example of an LTL trace that satisfies their answer but not the correct answer. &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
    &lt;img src=&quot;https://blog.brownplt.org/img/ltl-tutor-stepper.png&quot; alt=&quot; In this example of interactive stepper usage, the user examines the satisfaction of the formula (G (z &amp;lt;-&amp;gt; X(a))) in the third state of a trace. While the overall formula is not satisfied at this moment in time, the sub-formula (X a) is satisfied. This allows learners to explore where their understanding of a formula may have diverged from the correct answer.&quot; /&gt;
    &lt;figcaption&gt; In this example of interactive stepper usage, the user examines the satisfaction of the formula &lt;code&gt;(G (z &amp;lt;-&amp;gt; X(a)))&lt;/code&gt; in the third state of a trace. While the overall formula is not satisfied at this moment in time, the sub-formula &lt;code&gt;(X a)&lt;/code&gt; is satisfied. This allows learners to explore where their understanding of a formula may have diverged from the correct answer.
 &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;If learners consistently demonstrate the same misconception, the tutor provides them further &lt;strong&gt;insight&lt;/strong&gt; in the form of tailored text grounded in our previous research.&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
    &lt;img src=&quot;https://blog.brownplt.org/img/ltl-tutor-globally-insight.png&quot; alt=&quot;Here, a student who consistently assumes the presence of the `Globally` operator even when it is not present, is given further insight into the pertinent semantics of the operator.&quot; /&gt;
    &lt;figcaption&gt; Here, a student who consistently assumes the presence of the `Globally` operator even when it is not present, is given further insight into the pertinent semantics of the operator. &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;Once it has a history of misconceptions exhibited by the student, the tutor &lt;strong&gt;generates&lt;/strong&gt; novel, personalized question sets designed to drill students on their specific weaknesses. As students use the tutor, the system updates its understanding of their evolving needs, generating question sets to address newly uncovered or pertinent areas of difficulty.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also designed the LTL Tutor with practical instructor needs in mind:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Curriculum Agnostic&lt;/strong&gt;: The LTL Tutor is flexible and not tied to any specific curriculum. You can seamlessly integrate it into your existing course without making significant changes. It both generates exercises for students and allows you to import your own problem sets.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Detailed Reporting&lt;/strong&gt;: To track your class’s progress effectively, you can create a unique course code for your students to enter, so you can get detailed insights into their performance.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Self-Hostable&lt;/strong&gt;: If you prefer to have full control over your data, the LTL Tutor can easily be &lt;a href=&quot;https://github.com/brownplt/LTLTutor/wiki/Hosting-the-LTL-Tutor&quot;&gt;self-hosted&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To learn more about the Tutor, please &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/pgnk-ltl-tutor/&quot;&gt;read our paper&lt;/a&gt;!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Misconceptions In Finite-Trace and Infinite-Trace Linear Temporal Logic</title>
   <link href="http://blog.brownplt.org/2024/07/07/little-tricky-logics-2.html"/>
   <updated>2024-07-07T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2024/07/07/little-tricky-logics-2</id>
   <content type="html">&lt;p&gt;&lt;em&gt;We now also have an
&lt;a href=&quot;/2024/08/08/ltltutor.html&quot;&gt;automated tutor&lt;/a&gt;
that puts this material to work to help students directly.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Over the past three years and with a multi-national group of collaborators, we
have been digging deeper into misconceptions in LTL (Linear Temporal Logic) and
studying misconceptions in LTLf, a promising variant of LTL restricted to
finite traces. Why LTL and LTLf? Because beyond their traditional uses
in verification and now robot synthesis, they support even more applications, from
&lt;a href=&quot;https://doi.org/10.24963/kr.2023/65&quot;&gt;image processing&lt;/a&gt;
to &lt;a href=&quot;https://quickstrom.io/&quot;&gt;web-page testing&lt;/a&gt;
to &lt;a href=&quot;https://rulemining.org/&quot;&gt;process-rule mining&lt;/a&gt;.
Why study misconceptions? Because ultimately, human users need to fully understand
what a formula says before they can safely apply synthesis tools and the like.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/2022/11/05/little-tricky-logics.html&quot;&gt;Our original post on LTL misconceptions&lt;/a&gt;
gives more background and motivation. It also explains the main types of questions
we use: translations between English specifications and formal specifications.&lt;/p&gt;

&lt;p&gt;So what’s new this time around?&lt;/p&gt;

&lt;p&gt;First, we provide two test instruments that have been field tested
with several audiences:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;One instrument &lt;a href=&quot;/img/ltlf-instrument.pdf&quot;&gt;[PDF]&lt;/a&gt;
focuses on the &lt;strong&gt;delta&lt;/strong&gt; between LTL and LTLf.
If you know LTL but not LTLf, &lt;a href=&quot;https://brown.co1.qualtrics.com/jfe/form/SV_38fUSW6EHtaB3My&quot;&gt;give it a try&lt;/a&gt;!
You’ll come away with hands-on experience of the special constraints that
finite traces bring.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The other instrument &lt;a href=&quot;/img/ltl-beginner-instrument.pdf&quot;&gt;[PDF]&lt;/a&gt;
is for LTL beginners — to see what preconceptions
they bring to the table. It assumes basic awareness of G (“always”), F
(“eventually”), and X (“next state”). It does not test the U (“until”)
operator.
Live survey &lt;a href=&quot;https://brown.co1.qualtrics.com/jfe/form/SV_6nG97IU77mCKX0a&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Second, we find evidence for several concrete misconceptions in the data. Some
misconceptions were identified in prior work and are confirmed here. Others are
new to this work.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;For example, consider the LTLf formula: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;G(red =&amp;gt; X(X(red)))&lt;/code&gt;.
What finite traces satisfy it?&lt;/p&gt;

  &lt;p&gt;In particular, can any &lt;em&gt;finite&lt;/em&gt; traces that have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;red&lt;/code&gt; true at some point
satisfy the formula?&lt;/p&gt;

  &lt;details&gt;&lt;summary&gt;Click to show answer:&lt;/summary&gt;No, because whenever
&lt;code style=&quot;font-family: Courier; font-size: 10pt&quot;&gt;red&lt;/code&gt;
is true it must be true again two states later, but every finite trace will
eventually run out of states.&lt;/details&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Now consider the LTL formula &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F(X(X(red)))&lt;/code&gt;. Is it true for an infinite trace
where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;red&lt;/code&gt; is true exactly once?&lt;/p&gt;

  &lt;details&gt;&lt;summary&gt;Click to show answer:&lt;/summary&gt;Yes. But interestingly, some of
our LTL beginners said no on the grounds that
&lt;code style=&quot;font-family: Courier; font-size: 10pt&quot;&gt;X(X(red))&lt;/code&gt;
ought to &quot;spread out&quot;
and constrain three states in a row.
&lt;/details&gt;
&lt;/blockquote&gt;

&lt;p&gt;Third, we provide a code book of misconceptions and how to identify them in
new data &lt;a href=&quot;/img/fm24-code-book.pdf&quot;&gt;[PDF]&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For more details, see
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/gpdzdkmnz-miscon-finite-infinite-ltl/&quot;&gt;the paper&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;See also our
&lt;a href=&quot;https://www.ltl-tutor.xyz/&quot;&gt;LTL Tutor&lt;/a&gt; (traditional LTL only, not finite-trace).&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Iterative Student Program Planning using Transformer-Driven Feedback</title>
   <link href="http://blog.brownplt.org/2024/07/05/plan-feedback-llms.html"/>
   <updated>2024-07-05T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2024/07/05/plan-feedback-llms</id>
   <content type="html">&lt;p&gt;We’ve had &lt;a href=&quot;/2023/12/27/plan-notations.html&quot;&gt;a few projects&lt;/a&gt; now that address this idea of teaching students to plan out solutions to programming problems. A thus-far missing but critical piece is feedback on this planning process. Ideally we want to give students feedback on their plans &lt;em&gt;before&lt;/em&gt; they commit to any code details. Our &lt;a href=&quot;/2022/07/09/plan-comp-hof.html&quot;&gt;early studies&lt;/a&gt; had students express their plans in a semi-formalized way which would’ve allowed us to automatically generate feedback based on formal structure. However, our &lt;a href=&quot;/2023/12/27/plan-notations.html&quot;&gt;most recent project&lt;/a&gt; highlighted a strong preference towards more freedom in notation, with plans expressed in far less structured language. This presents a challenge when designing automated feedback.&lt;/p&gt;

&lt;p&gt;So how do we interpret plans written with little to no restrictions on notation or structure, in order to still give feedback? We throw it at an LLM, right?&lt;/p&gt;

&lt;p&gt;It’s never that simple. We first tried direct LLM feedback, handing the student plan to an LLM with instructions of what kinds of feedback to give. Preliminary feedback results ranged from helpful to useless to incorrect. Even worse, we couldn’t prevent the LLM from directly including a correct answer in its response.&lt;/p&gt;

&lt;p&gt;So we built a different kind of feedback system. Student plans, expressed mostly in English, are translated into code via an LLM. (We do &lt;strong&gt;not&lt;/strong&gt; allow the LLM to access the problem statement— otherwise it would silently correct student misconceptions when translating into code.) The resulting code is run against an instructor test suite, and the test suite results are shown to the student as feedback.&lt;/p&gt;

&lt;p&gt;When we deployed this system, we found that the results from running the LLM-generated code against our instructor test suite seemed to serve as a useful proxy for student plan correctness. However, many issues from the LLM still caused a great deal of student frustration, especially from the LLM not having access to details from the problem statement.&lt;/p&gt;

&lt;p&gt;LLMs are good at presenting correct code solutions and correcting errors, and there is clear incentive for these behaviors to improve. But these behaviors are sometimes counterproductive to student feedback. Creating LLM-based feedback systems still requires careful thought in both its design and presentation to students.&lt;/p&gt;

&lt;p&gt;For more detail on our design and results, &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/rsfk-planning-w-gpt-feedback/&quot;&gt;read here&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Differential Analysis: A Summary</title>
   <link href="http://blog.brownplt.org/2024/06/27/differential-analysis.html"/>
   <updated>2024-06-27T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2024/06/27/differential-analysis</id>
   <content type="html">&lt;p&gt;For multiple decades we have worked on a the problem of &lt;em&gt;differential analysis&lt;/em&gt;. This post explains where it comes from, what it means, and what its consequences are.&lt;/p&gt;

&lt;h1 id=&quot;context-verification&quot;&gt;Context: Verification&lt;/h1&gt;

&lt;p&gt;For decades, numerous researchers have worked on the problem of verification. To a first approximation, we can describe this problem as follows:&lt;/p&gt;

&lt;center&gt;
&lt;em&gt;P&lt;/em&gt; ⊧ ɸ
&lt;/center&gt;

&lt;p&gt;That is, checking whether some program &lt;em&gt;P&lt;/em&gt; satisfies some property ɸ. There have been many productive discussions about exactly what methods we should use, but this remains the fundamental question.&lt;/p&gt;

&lt;p&gt;Starting in around 2004, we started to build tools to verify a variety of interesting system descriptions (the &lt;em&gt;P&lt;/em&gt;s), starting with access-control policies. They could also be security policies, network configurations, and more. We especially recognized that many of these system descriptions are (sufficiently) sub-Turing-complete, which means we can apply rich methods to precisely answer questions about them. That is, there is a rich set of problems we can verify.&lt;/p&gt;

&lt;h1 id=&quot;the-problem&quot;&gt;The Problem&lt;/h1&gt;

&lt;p&gt;Attractive as this idea is, it runs into a significant problem in practice. When you speak to practitioners, you find that they are not short of system descriptions (&lt;em&gt;P&lt;/em&gt;s), but they are severely lacking in properties (ɸs). The problem is not what some might imagine — that they can’t express their properties in some precise logic (which is a &lt;a href=&quot;/2022/11/05/little-tricky-logics.html&quot;&gt;separate problem&lt;/a&gt;!) — but rather that they struggle to express non-trivial properties &lt;em&gt;at all&lt;/em&gt;. A typical conversation might go like:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We have a tool for verification!&lt;/li&gt;
  &lt;li&gt;Nice, what does it do?&lt;/li&gt;
  &lt;li&gt;It consumes system descriptions of the kind you produce!&lt;/li&gt;
  &lt;li&gt;Oh, that’s great!&lt;/li&gt;
  &lt;li&gt;You just need to specify your properties.&lt;/li&gt;
  &lt;li&gt;My what?&lt;/li&gt;
  &lt;li&gt;Your properties! What you want your system to do!&lt;/li&gt;
  &lt;li&gt;I don’t have any properties!&lt;/li&gt;
  &lt;li&gt;But what do you want the system to &lt;em&gt;do&lt;/em&gt;?&lt;/li&gt;
  &lt;li&gt;… Work correctly?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not to mock practitioners: not at all. Quite the contrary! Even formal methods experts would struggle to precisely describe the expected behavior of complex systems. In fact, talk to formal methods researchers long enough and they’ll admit knowing that this is a problem. It’s just not something we like to think about.&lt;/p&gt;

&lt;h1 id=&quot;an-alternative&quot;&gt;An Alternative&lt;/h1&gt;

&lt;p&gt;In fact, the “practitioner” answer shows us the path forward. What does it mean for a system to “work”? How does a system’s maintainer know that it “works”?&lt;/p&gt;

&lt;p&gt;As a practical matter, many things help us confirm that a system is working well enough. We might have some test suites, we might have monitoring of its execution, we observe it run and use it; lots of people are using it every day; we might even have verified a few properties of a few parts! The net result is that we have &lt;em&gt;confidence&lt;/em&gt; in a system.&lt;/p&gt;

&lt;p&gt;And then, things happen! Typically, one of two things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We find a bug, and need to fix it.&lt;/li&gt;
  &lt;li&gt;We modify an existing feature or add a new one (or — all too rarely — remove one!).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the problem we run into is the following:&lt;/p&gt;

&lt;center&gt;
&lt;b&gt;How do we transfer the confidence we had&lt;br /&gt;in the old version to the new one?&lt;/b&gt;
&lt;/center&gt;

&lt;p&gt;Put differently, the core of formal methods is checking for &lt;em&gt;compatibility&lt;/em&gt; between two artifacts. Traditionally, we have a system description (&lt;em&gt;P&lt;/em&gt;) and a property (ɸ); these are meant to be expressed independent of one another, so that compatibility gives us confidence and incompatibility indicates an error. But now we have two different artifacts: an old system (call it &lt;em&gt;P&lt;/em&gt;) and a new one (call it &lt;em&gt;P’&lt;/em&gt;). These are obviously not going to be the same (except in rare cases; see below), but broadly, we want to know, how are they different?&lt;/p&gt;

&lt;center&gt;
&lt;em&gt;P&lt;/em&gt; - &lt;em&gt;P&apos;&lt;/em&gt;
&lt;/center&gt;

&lt;p&gt;Of course, what we care about is not the &lt;em&gt;syntactic&lt;/em&gt; difference, but the &lt;em&gt;semantic&lt;/em&gt; change. Large syntactic differences may have small semantic ones and vice versa.&lt;/p&gt;

&lt;h1 id=&quot;defining-the-difference&quot;&gt;Defining the Difference&lt;/h1&gt;

&lt;p&gt;Computing the semantic difference is often not easy. There is a long line of work of computing the difference of programs. However, it is difficult for Turing-complete languages; it is also not always clear what the &lt;em&gt;type&lt;/em&gt; of the difference should be. Computing it is a lot easier when the language is sub-Turing-complete (as our papers show). The question of exactly what a “difference” is is also interesting.&lt;/p&gt;

&lt;p&gt;Many of the system description languages we have worked with tend to be of the form &lt;em&gt;Request&lt;/em&gt; ⇒ &lt;em&gt;Response&lt;/em&gt;. For instance, an access control policy might have the type:&lt;/p&gt;

&lt;center&gt;
&lt;em&gt;Request&lt;/em&gt; ⇒ {Accept, Deny}
&lt;/center&gt;

&lt;p&gt;(In practice, policy languages can be much richer, but this suffices for illustration.) So what is the type of the &lt;em&gt;difference&lt;/em&gt;? It maps every request to the &lt;em&gt;cross-product&lt;/em&gt; of responses:&lt;/p&gt;

&lt;center&gt;
&lt;em&gt;Request&lt;/em&gt; ⇒ {Accept↦Accept, Deny↦Deny, Accept↦Deny, Deny↦Accept}
&lt;/center&gt;

&lt;p&gt;That is: some requests that used to be accepted still are; some that were denied still are; but some that were accepted are now deined, and some that were denied are now accepted. (This assumes the domains are exactly the same; otherwise some requests that previously produced a decision no longer do, and vice versa. We’ll assume you can work out the details of domains with bottom values.) The &lt;em&gt;difference&lt;/em&gt; is of course the requests whose outcomes change: in this case,&lt;/p&gt;

&lt;center&gt;
&lt;em&gt;Request&lt;/em&gt; ⇒ {Accept↦Deny, Deny↦Accept}
&lt;/center&gt;

&lt;h1 id=&quot;using-the-difference&quot;&gt;Using the Difference&lt;/h1&gt;

&lt;p&gt;Depending on how we compute the difference, we can treat the difference essentially as a &lt;em&gt;database&lt;/em&gt;. That is, it is a set of pairs of request and change-of-response. The database perspective is very productive, because we can do many things with this database:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Queries&lt;/strong&gt;: What is the set of requests whose decisions go from Deny↦Accept? These are places where we might look for data leaks.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Views&lt;/strong&gt;: What are all the requests whose decisions go from Accept↦Deny? These are all the requests that lost access. We might then want to perform queries over this smaller database: e.g., who are the entities whose requests fall in it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And perhaps most surprisingly:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Verification&lt;/strong&gt;: Confirm that as a result of this change, certain entities did not gain access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In our experience, administrators who would not be able to describe properties of their system can define properties of their &lt;em&gt;changes&lt;/em&gt;. Indeed, classical verification even has a name for some such properties: they’re called “frame conditions”, and mean, in effect, “and nothing else changed”. Here, we can actually check for these. It’s worth noting that these properties are not true of either the old or new systems! For instance, certain individuals may have had privileges before and will have them after the alteration; all we’re checking is that their privileges did not &lt;em&gt;change&lt;/em&gt;.&lt;/p&gt;

&lt;h1 id=&quot;uses&quot;&gt;Uses&lt;/h1&gt;

&lt;p&gt;Having a general “semantic difference engine”, and being able to query it (interactively), is very powerful. We can perform all the operations we have described above. We can use it to check the consequences of an intended edit. In some rare cases, we expect the difference to be empty: e.g., when we refactor the policy to clean it up syntactically, but expect that the refactoring had no semantic impact. Finally, a semantic differencing engine is also useful as an oracle when performing mutation testing, as &lt;a href=&quot;https://dl.acm.org/doi/10.1145/1242572.1242663&quot;&gt;Martin and Xie&lt;/a&gt; demonstrated.&lt;/p&gt;

&lt;h1 id=&quot;a-cognitive-perspective&quot;&gt;A Cognitive Perspective&lt;/h1&gt;

&lt;p&gt;We think there are a few different, useful framings of differential analysis.&lt;/p&gt;

&lt;p&gt;One might sound like a truism: we’re not very good at thinking about the things that we didn’t think about. That is, when we make a change to the system, there was some intent behind the change; but it can be very difficult to determine all the &lt;em&gt;consequences&lt;/em&gt; of that change. Our focus on the intended change can easily blind us thinking through the consequences. Overcoming these blind spots is very difficult for humans. A semantic differential analysis engine lays them bare.&lt;/p&gt;

&lt;p&gt;Another is that we lack good tools to figure out what the properties of a system should be. Model-exploration tools (such as Alloy, or our derivative of it,
&lt;a href=&quot;/2024/04/21/forge.html&quot;&gt;Forge&lt;/a&gt;) are useful at prompting people to think about how they expect systems to behave and not behave. Differential output can also be such a spur: in articulating why something should or should not happen with a change, we learn more about the system itself.&lt;/p&gt;

&lt;p&gt;Finally, it’s worth distinguishing the different conditions that lead to system changes. When working on features, we can often do so with some degree of flexibility. But when fixing bugs, we’re often in a hurry: we need to make a change to immediately block, say, a data leakage. If we’re being principled, we might add some tests to check for the intended behavior (and perhaps also to avoid regression); but at that moment, we are likely to be in an especially poor shape to think through unintended consequences. Differential analysis serves as an aid in preventing fixing one problem introducing another.&lt;/p&gt;

&lt;h1 id=&quot;readings&quot;&gt;Readings&lt;/h1&gt;

&lt;p&gt;Here are some of our papers describing differential analysis (which we have also called “change-impact analysis” in the past):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;For access-control policies: &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/fkmt-verif-change-impact-xacml/&quot;&gt;paper&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;For obligations: &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/dfk-spec-reason-dyn-acc-ctrl-pol/&quot;&gt;paper&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;For firewalls: &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/nbfdk-margrave-firewall/&quot;&gt;paper&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;For SDNs:
&lt;a href=&quot;/2015/06/02/flowlog5.html&quot;&gt;blog&lt;/a&gt;;
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/nfk-static-diff-anal-sdn/&quot;&gt;paper&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Forge: A Tool to Teach Formal Methods</title>
   <link href="http://blog.brownplt.org/2024/04/21/forge.html"/>
   <updated>2024-04-21T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2024/04/21/forge</id>
   <content type="html">&lt;p&gt;For the past decade we have been studying how best to get students into formal methods (FM). Our focus is not on the 10% or so of students who will automatically gravitate towards it, but on the “other 90%” who don’t view it as a fundamental part of their existence (or of the universe). In particular, we decided to infuse FM thinking into the students who go off to build &lt;em&gt;systems&lt;/em&gt;. Hence the course, &lt;a href=&quot;https://cs.brown.edu/courses/info/csci1710/&quot;&gt;Logic for Systems&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The bulk of the course focuses on solver-based formal methods. In particular, we began by using &lt;a href=&quot;https://alloytools.org/&quot;&gt;Alloy&lt;/a&gt;. Alloy comes with numerous benefits: it feels like a programming language, it can “Run” code like an IDE, it can be used for both verification and state-exploration, it comes with a nice visualizer, and it allows lightweight exploration with gradual refinement.&lt;/p&gt;

&lt;p&gt;Unfortunately, over the years we have also run into various issues with Alloy, a full catalog of which is in the paper. In response, we have built a new FM tool called &lt;a href=&quot;https://forge-fm.org&quot;&gt;Forge&lt;/a&gt;. Forge is distinguished by the following three features:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Rather than plunging students into the full complexity of Alloy’s language, we instead layer it into a series of &lt;em&gt;language levels&lt;/em&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We use the &lt;a href=&quot;https://sterling-js.github.io/&quot;&gt;Sterling&lt;/a&gt; visualizer by default, which you can think of as a better version of Alloy’s visualizer. But there’s much more! Sterling allows you to craft custom visualizations. We use this to create &lt;em&gt;domain-specific visualizations&lt;/em&gt;. As we show in the paper, the default visualization can produce unhelpful, confusing, or even outright misleading images. Custom visualization takes care of these.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;In the past, we have explored
&lt;a href=&quot;/2021/11/24/pbt-revisited.html&quot;&gt;property-based testing&lt;/a&gt;
as a way to get students on the road from programming to FM. In turn, we are asking the question, “What does &lt;em&gt;testing&lt;/em&gt; look like in this FM setting?” Forge provides preliminary answers, with more to come.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Just to whet your appetite, here is an example of what a default Sterling output looks like (Alloy’s visualizer would produce something similar, with fewer distinct colors, making it arguably even harder to see):&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/sterling-default-2024.png&quot; alt=&quot;Default Sterling output&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here’s what custom visualization shows:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/sterling-custom-2024.png&quot; alt=&quot;Custom Sterling output&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;See the difference?&lt;/p&gt;

&lt;p&gt;For more details, see &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/ngp----forge/&quot;&gt;the paper&lt;/a&gt;. And please &lt;a href=&quot;https://forge-fm.org&quot;&gt;try out Forge&lt;/a&gt;!&lt;/p&gt;

&lt;h3 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;/h3&gt;

&lt;p&gt;We are grateful for support from the U.S. National Science Foundation (&lt;a href=&quot;https://www.nsf.gov/awardsearch/showAward?AWD_ID=2208731&quot;&gt;award #2208731&lt;/a&gt;).&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Finding and Fixing Standard Misconceptions About Program Behavior</title>
   <link href="http://blog.brownplt.org/2024/04/12/behavior-misconceptions.html"/>
   <updated>2024-04-12T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2024/04/12/behavior-misconceptions</id>
   <content type="html">&lt;p&gt;A large number of modern languages — from Java and C# to Python and JavaScript to Racket and OCaml — share a common semantic core:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;variables are lexically scoped&lt;/li&gt;
  &lt;li&gt;scope can be nested&lt;/li&gt;
  &lt;li&gt;evaluation is eager&lt;/li&gt;
  &lt;li&gt;evaluation is sequential (per “thread”)&lt;/li&gt;
  &lt;li&gt;variables are mutable, but first-&lt;em&gt;order&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;structures (e.g., vectors/arrays and objects) are mutable, and first-&lt;em&gt;class&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;functions can be higher-order, and close over lexical bindings&lt;/li&gt;
  &lt;li&gt;memory is managed automatically (e.g., garbage collection)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We call this the &lt;em&gt;Standard Model of Languages&lt;/em&gt; (SMoL).&lt;/p&gt;

&lt;p&gt;SMoL potentially has huge pedagogic benefit:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;If students master SMoL, they have a good handle on the core of several of these languages.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Students may find it easier to port their knowledge between languages: instead of being lost in a sea of different syntax, they can find familiar signposts in the common semantic features. This may also make it easier to learn new languages.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The &lt;em&gt;differences&lt;/em&gt; between the languages are thrown into sharper contrast.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Students can see that, by going beyond syntax, there are several big semantic ideas that underlie all these languages, many of which we consider “best practices” in programming language design.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We have therefore spent the past four years working on the pedagogy of SMoL:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Finding errors in the understanding of SMoL program behavior.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Finding the (mis)conceptions behind these errors.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Collating these into clean instruments that are easy to deploy.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Building a &lt;em&gt;tutor&lt;/em&gt; to help students correct these misconceptions.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Validating all of the above.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are now ready to present a checkpoint of this effort. We have distilled the essence of this work into a tool:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://smol-tutor.xyz/&quot;&gt;The SMoL Tutor&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It identifies and tries to fix student misconceptions. The Tutor assumes users have a baseline of programming knowledge typically found after 1–2 courses: variables, assignments, structured values (like vectors/arrays), functions, and higher-order functions (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lambda&lt;/code&gt;s). Unlike most tutors, instead of &lt;em&gt;teaching&lt;/em&gt; these concepts, it investigates how well the user actually &lt;em&gt;understands&lt;/em&gt; them. Wherever the user makes a mistake, the tutor uses an educational device called a &lt;em&gt;refutation text&lt;/em&gt; to help them understand where they went wrong and to correct their conception. The Tutor lets the user switch between multiple syntaxes, both so they can work with whichever they find most comfortable (so that syntactic unfamiliarity or discomfort does not itself become a source of errors), and so they can see the semantic unity beneath these languages.&lt;/p&gt;

&lt;p&gt;Along the way, to better classify student responses, we invent a concept called the &lt;em&gt;misinterpreter&lt;/em&gt;. A misinterpreter is an intentionally incorrect interpreter. Concretely, for each misconception, we create a corresponding misinterpreter: one that has the same semantics as SMoL &lt;em&gt;except&lt;/em&gt; on that one feature, where it implements the misconception instead of the correct concept. By making misconceptions executable, we can mechanically check whether student responses correspond to a misconception.&lt;/p&gt;

&lt;p&gt;There are many interesting lessons here:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Many of the problematic programs are likely to be startlingly simple to experts.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The combination of state, aliasing, and functions is complicated for students. (Yet most &lt;em&gt;introductory&lt;/em&gt; courses plunge students into this maelstrom of topics without a second thought or care.)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Misinterpreters are an interesting concept in their own right, and are likely to have value independent of the above use.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, we have not directly studied the following claims but believe they are well warranted based on observations from this work and from experience teaching and discussing programming languages:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;In SMoL languages, local and top-level bindings behave the same as the binding induced by a function call. However, students often do not realize that these have a uniform semantics. In part this may be caused by our focus on the “call by” terminology, which focuses on calls (and makes them seem special). We believe it would be an improvement to replace these with “bind by”.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We also believe that the terms “call-by-value” and “call-by-reference” are so hopelessly muddled at this point (between students, instructors, blogs, the Web…) that finding better terminology overall would be helpful.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The way we informally talk about programming concepts (like “pass a variable”), and the syntactic choices our languages make (like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return x&lt;/code&gt;), are almost certainly also sources of confusion. The former can naturally lead students to believe variables are being aliased, and the latter can lead them to believe the &lt;em&gt;variable&lt;/em&gt;, rather than its &lt;em&gt;value&lt;/em&gt;, is being returned.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more details about the work, see &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/lk-smol-tutor/&quot;&gt;the paper&lt;/a&gt;. The paper is based on an old version of the Tutor, where all programs were presented in parenthetical syntax. The Tutor now supports multiple syntaxes, so you don’t have to worry about being constrained by that. Indeed, it’s being used right now in a course that uses Scala 3.&lt;/p&gt;

&lt;p&gt;Most of all, the &lt;a href=&quot;https://smol-tutor.xyz/&quot;&gt;SMoL Tutor&lt;/a&gt; is free to use! We welcome and encourage instructors of programming courses to consider using it — you may be surprised by the mistakes your students make on these seemingly very simple programs. But we also welcome learners of all stripes to give it a try!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Privacy-Respecting Type Error Telemetry at Scale</title>
   <link href="http://blog.brownplt.org/2024/02/02/privacy-telemetry.html"/>
   <updated>2024-02-02T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2024/02/02/privacy-telemetry</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Thesis&lt;/em&gt;: Programming languages would benefit hugely from telemetry. It would be extremely useful to know what people write, how they edit, what problems they encounter, etc.
&lt;em&gt;Problem&lt;/em&gt;: Observing programmers is very problematic. For students, it may cause anxiety and thereby hurt their learning (and grades). For professionals too it may cause anxiety, but it can also leak trade secrets.&lt;/p&gt;

&lt;p&gt;One very partial solution is to perform these observations in controlled settings, such as a lab study. The downside is that it is hard to get diverse populations of users, it’s hard to retain them for very long, it’s hard to pay for these studies, etc. Furthermore, the activities they perform in a lab study may be very different from what they would do in real use: i.e., lab studies especially lack &lt;em&gt;ecological validity&lt;/em&gt; when compared against many real-world programming settings.&lt;/p&gt;

&lt;p&gt;We decided to instead study a large number of programmers doing their normal work—but in a &lt;em&gt;privacy-respecting&lt;/em&gt; way. We collaborated with the &lt;a href=&quot;https://create.roblox.com/&quot;&gt;Roblox Studio&lt;/a&gt; team on this project. Roblox is a widely-used platform for programming and deploying games, and it has &lt;a href=&quot;https://corp.roblox.com/&quot;&gt;lots of users&lt;/a&gt; of all kinds of ages and qualifications. They range from people writing their first programs to developers working for game studios building professional games.&lt;/p&gt;

&lt;p&gt;In particular, we wanted to study a specific phenomenon: the uptake of types in Luau. &lt;a href=&quot;https://luau-lang.org/&quot;&gt;Luau&lt;/a&gt; is an extension of Lua that powers Roblox. It supports classic Lua programs, but also lets programmers gradually add types to detect bugs at compile time. We specifically wanted to see what kind of type errors people make when using Luau, with the goal of improving their experience and thereby hopefully increasing uptake of the language.&lt;/p&gt;

&lt;p&gt;Privacy-respecting telemetry sounds wonderful in theory but is very thorny in practice. We want our telemetry to have several properties:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;It must not transmit any private information. This may be more subtle than it sounds. Error messages can, for instance, contain the names of functions. But these names may contain a trade secret.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It must be fast on the client-side so that the programmer experience is not disrupted.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It must transmit only small amount of data, so as not to overload the database servers.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(The latter two are not specific to privacy, but are necessary when working at scale.)&lt;/p&gt;

&lt;p&gt;Our earlier, pioneering work on &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/mfk-measur-effect-error-msg-novice-sigcse/&quot;&gt;error message analysis&lt;/a&gt; was able to obtain a large amount of insight from logs. As a result of the above constraints, we cannot even pose many of the same questions in our setting.&lt;/p&gt;

&lt;p&gt;Nevertheless, we were able to still learn several useful things about Luau. For more details, see &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/gjkm-priv-pres-telemetry/&quot;&gt;the paper&lt;/a&gt;. But to us, this project is at least as interesting for the questions it inspires as for the particular solution or the insights gained from it. We hope to see many more languages incorporate privacy-respecting telemetry. (We’re pleased to see the Go team also thinking about these issues, as summarized in Russ Cox’s &lt;a href=&quot;https://research.swtch.com/telemetry&quot;&gt;transparent telemetry&lt;/a&gt; notes. While there are some differences between our approaches, our overarching goals and constraints are very much in harmony.)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Profiling Programming Language Learning</title>
   <link href="http://blog.brownplt.org/2024/02/01/ppll.html"/>
   <updated>2024-02-01T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2024/02/01/ppll</id>
   <content type="html">&lt;p&gt;Programmers profile programs. They use profiling when they suspect a program is not being as effective (performant) as they would like. Profiling helps them track down what is working well and what needs more work, and how best to use their time to make the program more effective.&lt;/p&gt;

&lt;p&gt;Programming language creators want their languages to be adopted. To that end, they create documentation, such as a book or similar written document. These are written with the best of intentions and following the best practices they know of. But are they effective? Are they engaging? How do they know? These are questions very much in the &lt;a href=&quot;https://dl.acm.org/doi/10.1145/2384592.2384597&quot;&gt;Socio-PLT&lt;/a&gt; mould proposed by Meyerovich and Rabkin.&lt;/p&gt;

&lt;p&gt;In addition, their goal in writing such documentation is that people learn about their language. But many people do not enjoy a passive reading experience or, even if they do, they won’t learn much from it.&lt;/p&gt;

&lt;p&gt;These two issues mesh together well. Books should be more interactive. Books should periodically stop readers and encourage them to think about what they’re reading:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If a listener nods his head when you’re explaining your program, wake him up.&lt;/p&gt;

  &lt;p&gt;—Alan Perlis&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Books should give readers feedback on how well they have been reading so far. And authors should use this information to drive the content of the book.&lt;/p&gt;

&lt;p&gt;We have been doing this in our &lt;a href=&quot;/2023/09/17/rust-ownership.html&quot;&gt;Rust Book experiment&lt;/a&gt;. There, the focus was on a single topic: ownership. But in fact we have been doing this across the whole book, and in doing so we have learned a great deal.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;We analyzed the trajectory of readers and showed that many drop out when faced with difficult language concepts like Rust’s ownership types. This suggests either revising how those concepts are presented, moving them later in the book, or splitting them into two parts, a gentle introduction that retains readers and a more detailed, more technical chapter later in the book once readers are more thoroughly invested.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We used both classical test theory and item response theory to analyze the characteristics of quiz questions. We found that better questions are more conceptual in nature, such as asking &lt;em&gt;why&lt;/em&gt; a program does not compile versus &lt;em&gt;whether&lt;/em&gt; a program compiles.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We performed 12 interventions into the book to help readers with difficult questions. We evaluated how well an intervention worked by comparing the performance of readers pre- and post-intervention on the question being targeted.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In other words, the profiler analogy holds: it helps us understand the behavior of “the program” (namely, users going through the book), suggests ways to improve it, and helps us analyze specific attempts at improvement and shows that they are indeed helpful.&lt;/p&gt;

&lt;p&gt;However, we did all this with a book for which, over 13 months, 62,526 readers answered questions 1,140,202 times. This is of no help to new languages who might struggle to get more than dozens of users! Therefore, &lt;em&gt;we sampled to simulate how well we would have fared on much smaller subsets of users&lt;/em&gt;. We show that for some of our analyses even 100 users would suffice, while others require around a 1000. These numbers—especially 100—are very much attainable for young languages.&lt;/p&gt;

&lt;p&gt;Languages are designed for adoption, but mere design is usually insufficient to enable it, as the Socio-PLT paper demonstrated. We hope work along these lines can help language designers get their interesting work into many more hands and minds.&lt;/p&gt;

&lt;p&gt;For more details, see &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/ck-prof-prog-lang-learn/&quot;&gt;the paper&lt;/a&gt;. Most of all, you can do this with your materials, too! The library for adding these quizzes is &lt;a href=&quot;https://github.com/cognitive-engineering-lab/mdbook-quiz&quot;&gt;available here&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Examplar Project: A Summary</title>
   <link href="http://blog.brownplt.org/2024/01/01/examplar.html"/>
   <updated>2024-01-01T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2024/01/01/examplar</id>
   <content type="html">&lt;p&gt;For the past several years, we have worked on a project called Examplar. This article summarizes the goals and methods of the project and provides pointers to more detailed articles describing it.&lt;/p&gt;

&lt;h1 id=&quot;context&quot;&gt;Context&lt;/h1&gt;

&lt;p&gt;When faced with an programming problem, computer science students all-too-often begin their implementations with an incomplete understanding of what the problem is asking, and may not realize until far into their development process (if at all) that they have solved the wrong problem. At best, a student realizes their mistake, suffers from some frustration, and is able to correct it before the final submission deadline. At worst, they might not realize their mistake until they receive feedback on their final submission, depriving them of the intended learning goal of the assignment.&lt;/p&gt;

&lt;p&gt;How can we help them with this? A common practice—used across disciplines—is to tell students, “explain the problem in your own words”. This is a fine strategy, except it demands far too much of the student. Any educator who has done this knows that most students rightly stumble through this exercise, usually because &lt;em&gt;they don’t have any better words than are already in the problem statement&lt;/em&gt;. So what was meant to be a comprehension exercise becomes a literary one; even if they can restate it very articulately, it may be because of verbal skills, not necessarily indicative of good understanding. And for complex problems, the whole exercise is somewhat futile. It’s all made even more difficult when students are not in their native language, etc.&lt;/p&gt;

&lt;p&gt;So we have the kernel of a good idea—asking students to read back their understanding—but words are a poor medium for it.&lt;/p&gt;

&lt;h1 id=&quot;examples&quot;&gt;Examples&lt;/h1&gt;

&lt;p&gt;Our idea is that writing &lt;em&gt;examples&lt;/em&gt;—using the syntax of text cases—is a great way to express understanding:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Examples are concrete.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It’s hard to be vague.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Difficulty writing down examples is usually indicative of broader difficulties with the problem, and a great, concrete way to initiate a discussion with course staff.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It gets a head-start on writing tests, which too many computing curricula undervalue (if they tackle it at all).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Best of all, because the examples &lt;em&gt;are&lt;/em&gt; executable, they can be run against implementations so that students get immediate feedback.&lt;/p&gt;

&lt;h1 id=&quot;types-of-feedback&quot;&gt;Types of Feedback&lt;/h1&gt;

&lt;p&gt;We want to give two kinds of feedback:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;em&gt;Correctness&lt;/em&gt;: Are they even correct? Do they match the problem specification?&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;em&gt;Thoroughness&lt;/em&gt;: How much of the problem space do they cover? Do they dodge misconceptions?&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consider (for example!) the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;median&lt;/code&gt; function. Here are two examples, in the syntax of Pyret:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-pyret&quot;&gt;check:
  median([list: 1, 2, 3]) is 2
  median([list: 1, 3, 5]) is 3
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These are both &lt;em&gt;correct&lt;/em&gt;, as running them against a correct implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;median&lt;/code&gt; will confirm, but are they &lt;em&gt;thorough&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;A student could, for instance, easily mistake &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;median&lt;/code&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mean&lt;/code&gt;. Note that the two examples above do not distinguish between the two functions! So giving students a thumbs-up at this point may still send them down the wrong path: they haven’t expressed &lt;em&gt;enough&lt;/em&gt; of an understanding of the problem.&lt;/p&gt;

&lt;h1 id=&quot;evaluating-examples&quot;&gt;Evaluating Examples&lt;/h1&gt;

&lt;p&gt;For this reason, Examplar runs a program against multiple implementations. One is a correct implementation (which we call the &lt;em&gt;wheat&lt;/em&gt;). (For technical reasons, it can be useful to have more than one correct implementation; see &lt;a href=&quot;#readings&quot;&gt;more below&lt;/a&gt;.) There are also several &lt;em&gt;buggy&lt;/em&gt; implementations (called &lt;em&gt;chaffs&lt;/em&gt;). Each example is first run against the wheat, to make sure it conforms to the problem specification. It is then run against each of the chaffs. Here’s what a recent version looks like:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/examplar-2019.svg&quot; alt=&quot;Screenshot of Examplar&apos;s Successor&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Every example is a &lt;em&gt;classifier&lt;/em&gt;: its job is to classify a program as correct or incorrect, i.e., to separate the wheat from the chaff. Of course, a particular buggy implementation may not be buggy in a way that a particular example catches. But across the board, the collection of examples should do a fairly good job of catching the buggy examples.&lt;/p&gt;

&lt;p&gt;Thus, for instance, one of our buggy implementations of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;median&lt;/code&gt; would be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mean&lt;/code&gt;. Because the two examples above are consistent with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mean&lt;/code&gt; as well, they would (incorrectly) pass &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mean&lt;/code&gt; instead of signaling an error. If we had no other examples in our suite, we would fail to catch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mean&lt;/code&gt; as buggy. That reflects directly as “the student has not yet confirmed that they understand the difference between the two functions”. We would want students to add examples like&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-pyret&quot;&gt;  median([list: 1, 3, 7]) is 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;that pass &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;median&lt;/code&gt; but &lt;em&gt;not&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mean&lt;/code&gt; to demonstrate that they have that understanding.&lt;/p&gt;

&lt;h1 id=&quot;answering-questions&quot;&gt;Answering Questions&lt;/h1&gt;

&lt;p&gt;Examplar is also useful as a “24 hour TA”. Consider this example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-pyret&quot;&gt;  median([list: 1, 2, 3, 4]) is ???
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What is the answer? There are three possible answers: the left-median (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;), right-median (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3&lt;/code&gt;), and mean-median (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2.5&lt;/code&gt;). A student could post on a forum and wait for a course staffer to read and answer. Or they can simply &lt;em&gt;formulate the question as a test&lt;/em&gt;: e.g.,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-pyret&quot;&gt;  median([list: 1, 2, 3, 4]) is 2.5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One of these three will pass the wheat. That tells the student the definition being used for this course, which may not have been fully specified in the problem statement. Similarly:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-pyret&quot;&gt;  median([list: ]) is ???  # the empty list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Indeed, we see students coming to course staff with questions like, “I see that Examplar said that …, and I wanted to know &lt;em&gt;why&lt;/em&gt; this is the answer”, which is a fantastic kind of question to hear.&lt;/p&gt;

&lt;h1 id=&quot;whence-chaffs&quot;&gt;Whence Chaffs?&lt;/h1&gt;

&lt;p&gt;It’s easy to see where to get the wheat: it’s just a correct implementation of the problem. But how do we get chaffs?&lt;/p&gt;

&lt;p&gt;An astute reader will have noticed that we are practicing a form of &lt;a href=&quot;https://en.wikipedia.org/wiki/Mutation_testing&quot;&gt;mutation testing&lt;/a&gt;. Therefore, it might be tempting to use mutation testing libraries to generate chaffs. This would be a mistake because it misunderstands the point of Examplar.&lt;/p&gt;

&lt;p&gt;We want students to use Examplar before they start programming, and as a warm-up activity to get their minds into the right problem space. That is not the time to be developing a test suite so extensive that it can capture every strange kind of error that might arise. Rather, we think of Examplar as performing what we call &lt;em&gt;conceptual mutation testing&lt;/em&gt;: we only want to make sure they have the right conception of the problem, and avoid misconceptions about it. Therefore, chaffs should correspond to high-level conceptual mistakes (like confusing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;median&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mean&lt;/code&gt;), not low-level programming errors.&lt;/p&gt;

&lt;h1 id=&quot;whence-misconceptions&quot;&gt;Whence Misconceptions?&lt;/h1&gt;

&lt;p&gt;There are many ways to find out what misconceptions students have. One is by studying the errors we ourselves make while formulating or solving the problem. Another is by seeing what kinds of questions they ask course staff and what corrections we need to make. But there’s one more interesting and subtle source: Examplar itself!&lt;/p&gt;

&lt;p&gt;Remember how we said we want examples to first pass the wheat? The failing ones are obviously…well, they’re wrong, but they may be wrong for an interesting reason. For instance, suppose we’ve defined &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;median&lt;/code&gt; to produce the mean-median. Now, if a student writes&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-pyret&quot;&gt;  median([list: 1, 2, 3, 4]) is 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;they are essentially expressing &lt;em&gt;their belief&lt;/em&gt; that they need to solve the right-median problem. Thus, by harvesting these “errors”, filtering, and then clustering them, we can determine what misconceptions students have because they told us—&lt;em&gt;in their own words&lt;/em&gt;!&lt;/p&gt;

&lt;h1 id=&quot;readings&quot;&gt;Readings&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Why you might want more than one wheat: &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/wkf-who-tests-testers/&quot;&gt;paper&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Introducing Examplar:
&lt;a href=&quot;/2020/01/11/examplar.html&quot;&gt;blog&lt;/a&gt;;
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/wk-examplar/&quot;&gt;paper&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Student use without coercion (in other words, gamified interfaces help…sometimes a bit too much):
&lt;a href=&quot;/2020/10/20/examplar.html&quot;&gt;blog&lt;/a&gt;;
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/wk-stud-write-test-no-coercion/&quot;&gt;paper&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;What help do students need that Examplar &lt;em&gt;can’t&lt;/em&gt; provide?
&lt;a href=&quot;/2021/10/02/examplar-weaknesses.html&quot;&gt;blog&lt;/a&gt;;
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/wk-examplar-unspecified/&quot;&gt;paper&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Turning wheat failures into misconceptions:
&lt;a href=&quot;/2022/10/15/problem-misconceptions.html&quot;&gt;blog&lt;/a&gt;;
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/pgnwk-making-hay-wheats/&quot;&gt;paper&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;From misconceptions to chaffs:
&lt;a href=&quot;/2023/10/31/conceptual-mutation-testing.html&quot;&gt;blog&lt;/a&gt;;
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/pgnk-conceptual-examplar/&quot;&gt;paper&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But this work has much earlier origins:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://htdp.org/&quot;&gt;&lt;em&gt;How to Design Programs&lt;/em&gt;&lt;/a&gt; has students write tests before programs. However, these tests are inert (i.e., there’s nothing to run them against), so students see little value in doing so. Examplar eliminates this inertness, and goes further.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Before Examplar, we had students provide peer-review on tests, and found it had several benefits:
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/pkf-ifpr-tests-tf-prog/&quot;&gt;paper&lt;/a&gt;. We also built a (no longer maintained) programming environment to support peer review:
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/ppkf-ct-multi-stage-in-flow/&quot;&gt;paper&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;One thing we learned is that these test suites can grow too large to generate useful feedback. This caused us to focus on the &lt;em&gt;essential&lt;/em&gt; test cases, out of which the idea of examples (as opposed to tests) evolved:
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/pcgfk-sweep-ess-eg-ifpr/&quot;&gt;paper&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>A Core Calculus for Documents</title>
   <link href="http://blog.brownplt.org/2023/12/28/document-calculus.html"/>
   <updated>2023-12-28T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2023/12/28/document-calculus</id>
   <content type="html">&lt;p&gt;Document languages like &lt;a href=&quot;https://commonmark.org/help/&quot;&gt;Markdown&lt;/a&gt;, &lt;a href=&quot;https://en.wikibooks.org/wiki/LaTeX&quot;&gt;LaTeX&lt;/a&gt;, &lt;a href=&quot;https://www.php.net/manual/en/tutorial.php&quot;&gt;PHP&lt;/a&gt;, and &lt;a href=&quot;https://shopify.github.io/liquid/&quot;&gt;Liquid&lt;/a&gt; are widely used to generate digital documents like PDFs and web pages.
Document languages often come with programming features like variables and macros to help authors write complex documents.
However, these document programming features are often designed or implemented in problematic ways, especially by the standards of a modern programming language.
For example:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;LaTeX’s macro system is not hygienic, which can cause macro arguments to conflict with a macro body. &lt;!-- Couldn&apos;t find a single citation for this one? --&gt;&lt;/li&gt;
  &lt;li&gt;PHP’s templating system relies on &lt;a href=&quot;https://www.php.net/manual/en/language.basic-syntax.phptags.php&quot;&gt;mutating a global output buffer&lt;/a&gt;, which means document fragments are not first-class values.&lt;/li&gt;
  &lt;li&gt;Liquid’s variable system provides a &lt;a href=&quot;https://shopify.github.io/liquid/basics/types/&quot;&gt;small and fixed set of data types&lt;/a&gt;, which limits the expressiveness of computations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These problems could all be addressed in more carefully designed document languages (we are personally fans of &lt;a href=&quot;https://docs.racket-lang.org/scribble/&quot;&gt;Scribble&lt;/a&gt; and &lt;a href=&quot;https://typst.app/&quot;&gt;Typst&lt;/a&gt;). But those languages, too, have their own failure modes. Therein lies a deeper problem: there are no &lt;em&gt;theoretical tools&lt;/em&gt; for reasoning about the design of a document language. Programming language theorists can use the lambda calculus to reason about the design of general-purpose programming languages. No such formal model exists for document languages.&lt;/p&gt;

&lt;p&gt;Our work addresses this issue by providing a &lt;em&gt;document calculus&lt;/em&gt;, or a formal model of the &lt;em&gt;programmatic aspects&lt;/em&gt; of document languages. We designed the document calculus in a series of &lt;em&gt;levels&lt;/em&gt; that each correspond to a family of existing document languages. Each level consists of a &lt;em&gt;domain&lt;/em&gt;, or the thing produced by the language, and a &lt;em&gt;constructor&lt;/em&gt;, or the feature used to construct elements of the domain. The levels are summarized in this table:&lt;/p&gt;

&lt;style&gt;
  #document-calculus {
    border-collapse: collapse;
  }

  #document-calculus th {
    text-align: center;
  }

  #document-calculus td {
    border: 1px solid gray;
    padding: 0.25em;
    text-align: left;
    font-size: 85%;
  }

  #document-calculus .highlight {
    margin: 0;
  }

  #document-calculus pre {   
    padding: 0.5em; 
  }
&lt;/style&gt;

&lt;table id=&quot;document-calculus&quot;&gt;
    &lt;tr&gt;
        &lt;th&gt;Domain&lt;/th&gt;
        &lt;th&gt;Ctor&lt;/th&gt;
        &lt;th&gt;Example Languages&lt;/th&gt;
        &lt;th&gt;Example Syntax&lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td rowspan=&quot;4&quot;&gt;String&lt;/td&gt;
        &lt;td&gt;Literal&lt;/td&gt;
        &lt;td&gt;Text files, &lt;em&gt;quoted strings&lt;/em&gt;&lt;/td&gt;
        &lt;td&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Hello World&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
 
  &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Program&lt;/td&gt;
        &lt;td&gt;PLs with string APIs, such as &lt;em&gt;Javascript&lt;/em&gt;&lt;/td&gt;
        &lt;td&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; World&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
               
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Template Literal&lt;/td&gt;
        &lt;td&gt;C &lt;code&gt;printf&lt;/code&gt;, Python f-strings, &lt;em&gt;Javascript template literals&lt;/em&gt;, Perl interpolated strings&lt;/td&gt;
        &lt;td&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;world&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;World&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;`Hello &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;world&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`&lt;/span&gt;          &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
          
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Template Program&lt;/td&gt;
        &lt;td&gt;C preprocessor, PHP, LaTeX, &lt;em&gt;Jinja (Python)&lt;/em&gt;, Liquid (Ruby), Handlebars (JS)&lt;/td&gt;
        &lt;td&gt;
            
            &lt;pre&gt;&lt;code&gt;{% set world = &quot;World&quot; %}
Hello {{ world }}&lt;/code&gt;&lt;/pre&gt;
            
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td rowspan=&quot;4&quot;&gt;Article&lt;/td&gt;
        &lt;td&gt;Literal&lt;/td&gt;
        &lt;td&gt;&lt;em&gt;CommonMark Markdown&lt;/em&gt;, Pandoc Markdown, HTML, XML&lt;/td&gt;
        &lt;td&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-markdown&quot; data-lang=&quot;markdown&quot;&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Hello &lt;span class=&quot;gs&quot;&gt;**World**&lt;/span&gt;         &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
           
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Program&lt;/td&gt;
        &lt;td&gt;PLs with document APIs, such as &lt;em&gt;Javascript&lt;/em&gt;&lt;/td&gt;
        &lt;td&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ul&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 
  &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ul&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Template Literal&lt;/td&gt;
        &lt;td&gt;JSX Javascript, Scala 2, VB.NET, &lt;em&gt;Scribble Racket&lt;/em&gt;, MDX Markdown, Lisp quasiquotes&lt;/td&gt;
        &lt;td&gt;
&lt;pre&gt;&lt;code&gt;@(define world &quot;World&quot;)
@itemlist{@item{
  Hello @bold{@world}}}
&lt;/code&gt;&lt;/pre&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Template Program&lt;/td&gt;
        &lt;td&gt;&lt;em&gt;Typst&lt;/em&gt;, Razor C#, Svelte Javascript, Markdoc Markdown&lt;/td&gt;
        &lt;td&gt;
            &lt;pre&gt;&lt;code&gt;#let world = [World]
- Hello *#world*&lt;/code&gt;&lt;/pre&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;The document calculus can inform the design of document languages in a few ways:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;The levels form a taxonomy which can help designers identify different points in the document language design space.&lt;/li&gt;
  &lt;li&gt;The calculus provides a reference semantics for a clean way to desugar key features like variables and loops.&lt;/li&gt;
  &lt;li&gt;The type system shows how to type-check a document prior to desugaring, including a proof of syntactic type safety.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For more details, see &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/ck-core-calc-doc-lambda-ultimate-doc/&quot;&gt;the paper&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Observations on the Design of Program Planning Notations for Students</title>
   <link href="http://blog.brownplt.org/2023/12/27/plan-notations.html"/>
   <updated>2023-12-27T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2023/12/27/plan-notations</id>
   <content type="html">&lt;p&gt;In &lt;a href=&quot;/2022/07/09/plan-comp-hof.html&quot;&gt;two&lt;/a&gt;
recent
&lt;a href=&quot;/2021/07/31/behavioral-hof.html&quot;&gt;projects&lt;/a&gt;
we’ve tried to make progress on the long-dormant topic of teaching
students how to &lt;em&gt;plan&lt;/em&gt; programs. Concretely, we chose higher-order
functions as our driving metaphor to address the problem of “What
language shall we use to express plans?” We showed that this was a
good medium for students. We also built some quite nice tool support
atop Snap&lt;em&gt;!&lt;/em&gt;. Finally, we were making progress on this long open
issue!&lt;/p&gt;

&lt;p&gt;Not so fast.&lt;/p&gt;

&lt;p&gt;We tried to replicate our previous finding with a new population of
students and somewhat (but not entirely) different problems. It didn’t
work well at all. Students made extensive complaints about the
tooling and, when given a choice, voted with their feet by not using
it.&lt;/p&gt;

&lt;p&gt;We then tried again, allowing them freedom in what notation they used,
but suggesting two: one was diagrammatic (essentially representing
dataflow), and the other was linear prose akin to a todo-list or
recipe. Students largely chose the latter, and also did a better job
with planning.&lt;/p&gt;

&lt;p&gt;Overall, this is a sobering result. It diminishes some of our earlier
success. At the same time, it sheds more light on the notations
students prefer. In particular, it returns to our earlier problem:
planning needs a vocabulary, and we are still far from establishing
one that students find comfortable and can use successfully. But it
also highlights deeper issues, such as the need to better support
students with composition. Critically, composition serves as a bridge
between more plan-oriented students and bricoleurs, making it
especially worthy of more study, no matter your position on how
students should or do design programs.&lt;/p&gt;

&lt;p&gt;For more details, see
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/rkf-obs-design-prog-plan-notations/&quot;&gt;the paper&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Conceptual Mutation Testing</title>
   <link href="http://blog.brownplt.org/2023/10/31/conceptual-mutation-testing.html"/>
   <updated>2023-10-31T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2023/10/31/conceptual-mutation-testing</id>
   <content type="html">&lt;style&gt;

   figure {
      display: block;
      margin: 0;
      padding: 0;
   }
   figcaption {
      font-family: Arial, sans-serif;
      font-size: 14px;
      font-weight: bold;
      color: black;
      margin-top: 10px;
      padding: 5px;
   }
&lt;/style&gt;

&lt;p&gt;&lt;em&gt;Here’s a &lt;a href=&quot;/2024/01/01/examplar.html&quot;&gt;summary of the full arc&lt;/a&gt;, including later work, of the Examplar project.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/2024/01/01/examplar.html&quot;&gt;The Examplar system&lt;/a&gt;
is designed to solve the documented phenomenon that students often misunderstand a programming problem statement and hence “solve” the wrong problem.  It does so by asking students to begin by writing input/output examples of program behavior, and evaluating them against correct and buggy implementations of the solution. Students refine and demonstrate their understanding of the problem by writing examples that correctly classify these implementations.&lt;/p&gt;

&lt;figure&gt;
    &lt;img src=&quot;https://blog.brownplt.org/img/examplar-1-buggy.png&quot; alt=&quot;Student-authored input-output examples have to both be consistent with the assignment, and also *catch* (not be consistent with) buggy implementations.&quot; /&gt;
    &lt;figcaption&gt;Student-authored input-output examples have to both be consistent with the assignment, and also catch (not be consistent with) buggy implementations. &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It is, however, very difficult to come up with good buggy candidates. These programs must correspond to the problem misconceptions students are most likely to have. Students can, otherwise, end up spending too much time catching them, and not enough time on the actual programming task. Additionally, a small number of very effective buggy implementations is far more useful than either a large number or ineffective ones (much less both).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/2022/10/15/problem-misconceptions.html&quot;&gt;Our previous research&lt;/a&gt; has shown that student-authored examples that fail the correct implementation often correspond to student misconceptions. Buggy implementations based on these misconceptions circumvent many of the pitfalls of expert-generated equivalents (most notably the ‘expert blind spot’). That work, however, leaves unanswered the crucial question of how to operationalize class-sourced misconceptions. Even a modestly sized class can generate thousands of failing examples per assignment. It takes a huge amount of manual effort, expertise, and time to extract misconceptions from this sea of failing examples.&lt;/p&gt;

&lt;p&gt;The key is to cluster these failing examples. The obvious clustering method – syntactic – fails miserably: small syntactic differences can result in large semantic differences, and vice versa (as the paper shows). Instead, we need a clustering technique that is based on the semantics of the problem.&lt;/p&gt;

&lt;p&gt;This paper instead presents a conceptual clustering technique based on key characteristics of each programming assignment. These clusters dramatically shrink the space that must be examined by course staff, and naturally suggest techniques for choosing buggy implementation suites. We demonstrate that these curated buggy implementations better reflect student misunderstandings than those generated purely by course staff. Finally, the paper suggests further avenues for operationalizing student misconceptions, including the generation of targeted hints.&lt;/p&gt;

&lt;p&gt;You can learn more about the work from &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/pgnk-conceptual-examplar/&quot;&gt;the paper&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Generating Programs Trivially: Student Use of Large Language Models</title>
   <link href="http://blog.brownplt.org/2023/09/19/generating-programs-trivially.html"/>
   <updated>2023-09-19T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2023/09/19/generating-programs-trivially</id>
   <content type="html">&lt;p&gt;The advent of large language models like GPT-3 has led to &lt;a href=&quot;https://www.nytimes.com/2023/01/16/technology/chatgpt-artificial-intelligence-universities.html&quot;&gt;growing concern from educators&lt;/a&gt; about how these models can be &lt;a href=&quot;https://www.washingtonpost.com/technology/2023/08/13/ai-chatgpt-chatbots-college-cheating/&quot;&gt;used and abused&lt;/a&gt; by students in order to help with their homework. In computer science, much of this concern centers on how LLMs automatically generate programs in response to textual prompts. Some institutions have gone as far as &lt;a href=&quot;https://www.theguardian.com/us-news/2023/jan/06/new-york-city-schools-ban-ai-chatbot-chatgpt&quot;&gt;instituting wholesale bans&lt;/a&gt; on the use of the tool. Despite all the alarm, however, little is known about whether and how students actually use these tools.&lt;/p&gt;

&lt;p&gt;In order to better understand the issue, we gave students in an upper-level formal methods course access to GPT-3 via &lt;a href=&quot;https://github.com/sidprasad/gpt-3-vscode&quot;&gt;a Visual Studio Code extension&lt;/a&gt;, and explicitly granted them permission to use the tool for course work. In order to mitigate any equity issues around access, we allocated $2500 in OpenAI credit for the course, enabling free access to the latest and greatest OpenAI models.&lt;/p&gt;

&lt;div id=&quot;usageq&quot; style=&quot;border:1px solid black;&quot; class=&quot;container&quot;&gt;
    &lt;p&gt;Can you guess the total dollar value of OpenAI credit used by students?&lt;/p&gt;
    &lt;input type=&quot;number&quot; id=&quot;answerInput&quot; value=&quot;2500&quot; /&gt;
    &lt;button onclick=&quot;usageAnswer()&quot;&gt;Guess&lt;/button&gt;
    &lt;p id=&quot;result1&quot;&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;We then analyzed the outcomes of this intervention, how and why students actually did and did not use the LLM.&lt;/p&gt;

&lt;div style=&quot;border:1px solid black;&quot; class=&quot;container&quot;&gt;
&lt;style&gt;
    .option-label img {
        width: 200px; /* Adjust the width of the images as needed */
        height: 200px; /* Adjust the height of the images as needed */
        vertical-align: middle;
    }


    [type=radio] + img {
    cursor: pointer;
    }

    [type=radio] { 
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
    }

    [type=radio]:checked + img {
    outline: 1px solid #f00;
    }
&lt;/style&gt;

&lt;script&gt;

    function usageAnswer() {
        // Get the user&apos;s answer from the input field
        var userAnswer = document.getElementById(&quot;answerInput&quot;).value;
        
        // Check if the user&apos;s answer is correct
        if (userAnswer &gt;= 10) {
            document.getElementById(&quot;result1&quot;).innerHTML = &quot;Way too high! Combined student OpenAI use totaled only $1.16.&quot;;
        } 
        else if (userAnswer &lt;= 0) {
            document.getElementById(&quot;result1&quot;).innerHTML = &quot;Your guess has to be a positive number. Students did use AskGPT!&quot;;
        }
        else if (window.isNaN(userAnswer)) {
            document.getElementById(&quot;result1&quot;).innerHTML = &quot;Your guess has to be a number.&quot;;
        }
        else {
            document.getElementById(&quot;result1&quot;).innerHTML = &quot;Good intuition! Combined student OpenAI use totaled only $1.16.&quot;;
        }
    }

    function checkAnswer() {
    var selectedAnswer = document.querySelector(&apos;input[name=&quot;answer&quot;]:checked&apos;);
    if (selectedAnswer) {
        var userAnswer = selectedAnswer.value;
        if (userAnswer === &quot;C&quot;) {
            document.getElementById(&quot;result2&quot;).innerHTML = &quot;Good intuition! &quot;;
        } else {
            document.getElementById(&quot;result2&quot;).innerHTML = &quot;Surprisingly, student usage looked more like Graph C.&quot;;
        }

        let c = document.getElementById(&quot;OptionC&quot;);
        c.style.border = &quot;5px solid green&quot;;

    } else {
        document.getElementById(&quot;result&quot;).innerHTML = &quot;Please make a guess!&quot;;
    }
}
&lt;/script&gt;
&lt;p&gt;Which of these graphs do you think best represents student use of GPT models over the semester?&lt;/p&gt;

&lt;form id=&quot;quizForm&quot;&gt;
    &lt;table&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;label class=&quot;option-label&quot;&gt;
                &lt;input type=&quot;radio&quot; name=&quot;answer&quot; value=&quot;A&quot; id=&quot;OptionA&quot; /&gt;
                &lt;img src=&quot;https://blog.brownplt.org/img/askgpt-option_a_image.PNG&quot; alt=&quot;Option A: A rough bell curve&quot; /&gt;
            &lt;/label&gt;
            &lt;/td&gt;
            &lt;td&gt;
            &lt;label class=&quot;option-label&quot;&gt;
                &lt;input type=&quot;radio&quot; name=&quot;answer&quot; value=&quot;B&quot; id=&quot;OptionB&quot; /&gt;
                &lt;img src=&quot;https://blog.brownplt.org/img/askgpt-option_b_image.PNG&quot; alt=&quot;Option B: Monotonically increasing usage over time&quot; /&gt;
            &lt;/label&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;label class=&quot;option-label&quot;&gt;
                &lt;input type=&quot;radio&quot; name=&quot;answer&quot; value=&quot;C&quot; /&gt;
                &lt;img src=&quot;https://blog.brownplt.org/img/askgpt-option_c_image.PNG&quot; alt=&quot;Option C: An initial spike and then no use&quot; id=&quot;OptionC&quot; /&gt;
            &lt;/label&gt;
            &lt;/td&gt;
            &lt;td&gt;
                &lt;label class=&quot;option-label&quot;&gt;
                    &lt;input type=&quot;radio&quot; name=&quot;answer&quot; value=&quot;D&quot; id=&quot;OptionD&quot; /&gt;
                    &lt;img src=&quot;https://blog.brownplt.org/img/askgpt-option_d_image.PNG&quot; alt=&quot;Option D: An initial spike and then steady use&quot; /&gt;
                &lt;/label&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/table&gt;
&lt;/form&gt;
&lt;button type=&quot;button&quot; onclick=&quot;checkAnswer()&quot;&gt;Guess&lt;/button&gt;
&lt;p id=&quot;result2&quot;&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;When surveyed, students overwhelmingly expressed concerns about using GPT to help with their homework. Dominant themes included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Fear that using LLMs would detract from learning.&lt;/li&gt;
  &lt;li&gt;Unfamiliarity with LLMs and issues with output correctness.&lt;/li&gt;
  &lt;li&gt;Fear of breaking course rules, despite being granted explicit permission to use GPT.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Much ink has been spilt on the effect of LLMs in education. While our experiment focuses only on a single course offering, we believe it can help re-balance the public narrative about such tools. Student use of LLMs may be influenced by two opposing forces. On one hand, competition for jobs may cause students to feel they must have “perfect” transcripts, which can be aided by leaning on an LLM. On the other, students may realize that getting an attractive job is hard, and decide they need to learn more in order to pass interviews and perform well to retain their positions.&lt;/p&gt;

&lt;p&gt;You can learn more about the work from the &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/pgnk-gpt-use-of-llms/&quot;&gt;paper&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>A Grounded Conceptual Model for Ownership Types in Rust</title>
   <link href="http://blog.brownplt.org/2023/09/17/rust-ownership.html"/>
   <updated>2023-09-17T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2023/09/17/rust-ownership</id>
   <content type="html">&lt;p&gt;Rust is establishing itself as the safe alternative to C and C++,
making it an essential component for building a future software univers that is correct, reliable,
and secure. Rust achieves this in part
through the use of a sophisticated type system based on the concept of
&lt;em&gt;ownership&lt;/em&gt;. Unfortunately, ownership is unfamiliar to most conventionally-trained
programmers. Surveys suggest that this central concept is also one of
Rust’s most difficult, making it a chokepoint in software progress.&lt;/p&gt;

&lt;p&gt;We have spent over a year understanding how ownership is currently
taught, in what ways this proves insufficient for programmers, and
looked for ways to improve their understanding. When confronted with a program containing an ownership violation, we found that Rust learners could generally predict the surface reason given by the compiler for rejecting the program. However, learners could often could not relate the surface reason to the underlying issues of memory safety and undefined behavior. This lack of understanding caused learners to struggle to idiomatically fix ownership errors.&lt;/p&gt;

&lt;p&gt;To address this, we created a new conceptual model for Rust ownership,
grounded in these studies. We then translated this model into two new
visualizations: one to explain how the type-system works, the other to
illustrate the impact on run-time behavior. Crucially, we configure
the compiler to ignore borrow-checker errors. Through this, we are
able to essentially run counterfactuals, and thereby illustrate the
ensuing undefined behavior.&lt;/p&gt;

&lt;p&gt;Here is an example of the type-system visualization:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/rust-static.png&quot; alt=&quot;A visualization of how the borrow checker works on a safe Rust program, using the metaphor of permissions to explain permissible operations at each step.&quot; style=&quot;max-width:100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And here is an example of the run-time visualization:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/rust-dynamic.png&quot; alt=&quot;A visualization of the state of memory at each stateent of an unsafe Rust program, showing how undefined behavior occurs with a use-after-free.&quot; style=&quot;max-width:100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We incorporated these diagrams into an
&lt;a href=&quot;https://rust-book.cs.brown.edu/&quot;&gt;experimental version&lt;/a&gt;
of &lt;em&gt;The Rust Programming Language&lt;/em&gt; by Klabnik and Nichols. The authors
graciously permitted us to create this fork and publicize it, and also
provided a link to it from the official edition. As a result, we were
able to test our tools on readers, and demonstrate that they do
actually improve Rust learning.&lt;/p&gt;

&lt;p&gt;The full details are in
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/cgk-grounded-model-rust-ownership/&quot;&gt;the paper&lt;/a&gt;.
Our view is that the new tools are preliminary, and other researchers
may come up with much better, more creative, and more effective
versions of them. Rather, the main contribution is an understanding of
how programmers do and don’t understand ownership, and in particular
its relationship to undefined behavior. It is therefore possible that
new pedagogies that make that connection clear may obviate the
need for some of these tools entirely.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>What Happens When Students Switch (Functional) Languages</title>
   <link href="http://blog.brownplt.org/2023/07/16/second-lang-fun.html"/>
   <updated>2023-07-16T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2023/07/16/second-lang-fun</id>
   <content type="html">&lt;p&gt;What happens when students learn a second programming language after
having gotten comfortable with one? This was a question of some
interest in the 1980s and 1990s, but interest in it diminished. Recent
work by Ethel Tshukudu and her collaborators have revived interest in
this question.&lt;/p&gt;

&lt;p&gt;Unfortunately, none of this work has really considered the role of
functional programming. This is especially worth considering in the
framework that Tshukudu’s work lays out, which is to separate syntax
and semantics. That is the issue we tackle.&lt;/p&gt;

&lt;p&gt;Specifically, we try to study two conditions:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;different syntax, similar semantics&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;similar syntax, different semantics&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the same semantics, any two sufficiently syntactically different
functional languages would do. The parenthetical syntax of the Lisp
family gives us a syntax that is clearly different from the infix
syntaxes of most other languages. In our particular case, we use
Racket and Pyret.&lt;/p&gt;

&lt;p&gt;The second case is trickier. For a controlled lab study, one could do
this with very controlled artificial languages. However, we are
interested in student experiences, which require curricula and
materials that made-up languages usually cannot provide.&lt;/p&gt;

&lt;p&gt;Instead, we find a compromise. The Pyret syntax was inspired by that
of Python, though it does have some differences. It comes with all the
curricular support we need. Therefore, we can compare it versus an
imperative curriculum in Python.&lt;/p&gt;

&lt;p&gt;You can read the details in
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/lkft-switch-fun-lang/&quot;&gt;the paper&lt;/a&gt;.
The work is less interesting for its answers than for its setup.  As a
community we know very little about this topic.  We hope the paper
will inspire other educators both through the questions we have asked
and the materials we have designed.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Typed-Untyped Interactions: A Comparative Analysis</title>
   <link href="http://blog.brownplt.org/2023/02/06/typed-untyped-comparison.html"/>
   <updated>2023-02-06T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2023/02/06/typed-untyped-comparison</id>
   <content type="html">&lt;p&gt;Dozens of languages today support gradual typing in some form or another.
What lessons can the designer of a new language learn from their experiences?&lt;/p&gt;

&lt;p&gt;As a starting point, let’s say that we want to maximize interoperability.
For most types in the language, untyped code should be able to make a value
that works for that type: type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Number&lt;/code&gt; should accept untyped numbers,
type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List(Number)&lt;/code&gt; should accept untyped lists, and so on.&lt;/p&gt;

&lt;p&gt;(This may seem like an obvious requirement for a type system that gets added
on top of an untyped language. But there are good reasons to break it — see
our &lt;a href=&quot;/2022/06/28/static-python.html&quot;&gt;earlier post&lt;/a&gt;
on Static Python.)&lt;/p&gt;

&lt;p&gt;The question now becomes: what sort of &lt;strong&gt;validation strategy&lt;/strong&gt; should typed code
use when an untyped value tries to cross a type boundary?
For example, when a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Number -&amp;gt; Number&lt;/code&gt; type receives an untyped function
there are at least three viable options:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Wrap the function in a proxy to make sure its behavior matches the type.&lt;/li&gt;
  &lt;li&gt;Leave the function unwrapped, but put checks at its call sites.&lt;/li&gt;
  &lt;li&gt;Do nothing! Trust the function.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both the research literature and the realm of production-ready languages
are full of ideas on this front. What was unclear (until now!) is how
the validation strategies &lt;em&gt;implicit&lt;/em&gt; across the landscape relate to one
another.&lt;/p&gt;

&lt;p&gt;With this paper, we introduce a toolbox of formal properties to pin down
the guarantees that gradual types can provide:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;type soundness&lt;/strong&gt; (generalized) for local type guarantees,&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;complete monitoring&lt;/strong&gt; for compositional type guarantees,&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;blame soundness&lt;/strong&gt; to judge the accuracy of validation errors, and&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;blame completeness&lt;/strong&gt; to judge the precision of validation errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also use an &lt;strong&gt;error preorder&lt;/strong&gt; to rank strategies by how early they
can detect a type validation mismatch.&lt;/p&gt;

&lt;p&gt;The upshot of all this is a positive characterization of the landscape. There
is no clear winner because there are other factors at play, such as performance
costs and the usefulness of types for debugging.  What we do gain is a solid
theoretical foundation to inform language designs.&lt;/p&gt;

&lt;p&gt;It’s all in &lt;a href=&quot;https://cs.utah.edu/~blg/publications/publications.html#gdf-toplas-2023&quot;&gt;the paper&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Little Tricky Logics</title>
   <link href="http://blog.brownplt.org/2022/11/05/little-tricky-logics.html"/>
   <updated>2022-11-05T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2022/11/05/little-tricky-logics</id>
   <content type="html">&lt;p&gt;&lt;em&gt;We also have
&lt;a href=&quot;/2024/07/07/little-tricky-logics-2.html&quot;&gt;followup work&lt;/a&gt;
that continues to explore LTL and now also studies finite-trace LTL.
In addition, we also have an
&lt;a href=&quot;/2024/08/08/ltltutor.html&quot;&gt;automated tutor&lt;/a&gt;
that puts this material to work to help students directly.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;LTL (Linear Temporal Logic) has long been central in computer-aided
verification and synthesis. Lately, it’s also been making significant
inroads into areas like planning for robots. LTL is powerful,
beautiful, and concise. What’s not to love?&lt;/p&gt;

&lt;p&gt;However, &lt;em&gt;any&lt;/em&gt; logic used in these settings must also satisfy the
central goal of being understandable by its users. Especially in a
field like synthesis, there is no second line of defense: a
synthesizer does exactly what the specification says. If the
specification is wrong, the output will be wrong in the same way.&lt;/p&gt;

&lt;p&gt;Therefore, we need to understand how people comprehend these
logics. Unfortunately, the human factors of logics has seen almost no
attention in the research community. Indeed, if anything, the
literature is rife with claims about what is “easy” or “intuitive”
without any rigorous justification for such claims.&lt;/p&gt;

&lt;p&gt;With this paper, we hope to change that conversation. We bring to bear
on this problem several techniques from diverse areas—but primarily
from education and other social sciences (with tooling provided by
computer science)—to understand the &lt;em&gt;misconceptions&lt;/em&gt; people have with
logics. Misconceptions are not merely mistakes; they are validated
understanding difficulties (i.e., having the wrong concept), and
hence demand much greater attention. We are especially inspired by
work in physics education on the creation of &lt;em&gt;concept inventories&lt;/em&gt;,
which are validated instruments for rapidly identifying misconceptions
in a population, and take steps towards the creation of one.&lt;/p&gt;

&lt;p&gt;Concretely, we focus on LTL (given its widespread use) and study the
problem of LTL understanding from three different perspectives:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;LTL to English&lt;/strong&gt;: Given an LTL formula, can a reader accurately
translate it into English? This is similar to what a person does when
reading a specification, e.g., when code-reviewing work or studying a
paper.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;English to LTL&lt;/strong&gt;: Given an English statement, can a reader
accurately express it in LTL?  This skill is essential for
specification and verification.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Furthermore, “understanding LTL” needs to be divided into two parts:
syntax and semantics. Therefore, we study a third issue:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Trace satisfaction&lt;/strong&gt;: Given an LTL formula and a trace (sequence
of states), can a reader accurately label the trace as satisfying or
violating? Such questions directly test knowledge of LTL semantics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our studies were conducted over multiple years, with multiple
audiences, and using multiple methods, with both formative and
confirmatory phases. The net result is that &lt;em&gt;we find &lt;strong&gt;numerous&lt;/strong&gt;
misconceptions in the understanding of LTL in &lt;strong&gt;all three&lt;/strong&gt;
categories.&lt;/em&gt; Notably, our studies are based on small formulas and
traces, so we expect the set of issues will only grow as the
instruments contain larger artifacts.&lt;/p&gt;

&lt;p&gt;Ultimately, in addition to&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;finding concrete misconceptions,&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;we also:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;create a codebook of misconceptions that LTL users have, and&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;provide instruments for finding these misconceptions.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We believe all three will be of immediate use to different
communities, such as students, educators, tool-builders, and designers
of new logic-based languages.&lt;/p&gt;

&lt;p&gt;For more details, see
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/gsnk-little-tricky-logic/&quot;&gt;the paper&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;See also our
&lt;a href=&quot;https://www.ltl-tutor.xyz/&quot;&gt;LTL Tutor&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Identifying Problem Misconceptions</title>
   <link href="http://blog.brownplt.org/2022/10/15/problem-misconceptions.html"/>
   <updated>2022-10-15T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2022/10/15/problem-misconceptions</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Here’s a &lt;a href=&quot;/2024/01/01/examplar.html&quot;&gt;summary of the full arc&lt;/a&gt;, including later work, of the Examplar project.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Our recent work is built on the documented research that students
often misunderstand a programming problem statement and hence “solve”
the wrong problem.  This not only creates frustration and wastes time,
it also robs them of whatever learning objective motivated the task.&lt;/p&gt;

&lt;p&gt;To address this, 
&lt;a href=&quot;/2024/01/01/examplar.html&quot;&gt;the Examplar system&lt;/a&gt;
asks students to first write &lt;em&gt;examples&lt;/em&gt;. These examples are evaluated
against &lt;em&gt;wheats&lt;/em&gt; (correct implementations) and &lt;em&gt;chaffs&lt;/em&gt; (buggy
implementations). Examples must pass the wheat, and correctly identify
as wrong as many chaffs as possible. Prior work explores this and
shows that it is quite effective.&lt;/p&gt;

&lt;p&gt;However, there’s a problem with chaffs. Students can end up spending
too much time catching them, and not enough time on the actual
programming task. Therefore, you want chaffs that correspond to the
problem misconceptions students are most likely to have. Having a
small number of very effective chaffs is far more useful than either a
large number or ineffective ones (much less both). But the open
question has always been, &lt;em&gt;how do we obtain chaffs&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Previously, chaffs were created by hand by experts. This was
problematic because it forces experts to imagine the kinds of problems
students might have; this is not only hard, it is bound to run into
expert blind spots. What other method do we have?&lt;/p&gt;

&lt;p&gt;This work is based on a very simple, clever observation: &lt;strong&gt;any time an
example fails a wheat, it may correspond to a student
misconception&lt;/strong&gt;. Of course, not all wheat failures are misconceptions!
It could be a typo, it could be a basic logical error, or it could
even be an attempt to game the wheat-chaff system. Do we know in what
ratio these occur, and can we use the ones that are misconceptions?&lt;/p&gt;

&lt;p&gt;This paper makes two main contributions:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;It shows that that many wheat failures really are
misconceptions.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It uses these misconceptions to formulate new chaffs, and shows
that they compare very favorably to expert-generated chaffs.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Furthermore, the work spans two kinds of courses: one is an
accelerated introductory programming class, while the other is an
upper-level formal methods course. We show that there is value in both
settings.&lt;/p&gt;

&lt;p&gt;This is just a first step in this direction; a lot of manual work went
into this research, which needs to be automated; we also need to
measure the direct impact on students. But it’s a very promising
direction in a few ways:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;It presents a novel method for finding misconceptions.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It naturally works around expert blind-spots.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;With more automation, it can be made lightweight.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In particular, if we can make it lightweight, we can apply it to
settings—even individual homework problems—that also manifest
misconceptions that need fixing, but could never afford heavyweight
concept-inventory-like methods for identifying them.&lt;/p&gt;

&lt;p&gt;You can learn more about the work from
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/pgnwk-making-hay-wheats/&quot;&gt;the paper&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Performance Preconceptions</title>
   <link href="http://blog.brownplt.org/2022/10/10/performance-preconceptions.html"/>
   <updated>2022-10-10T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2022/10/10/performance-preconceptions</id>
   <content type="html">&lt;p&gt;What do computer science students entering post-secondary (collegiate)
education think “performance” means?&lt;/p&gt;

&lt;p&gt;Who or what shapes these views?&lt;/p&gt;

&lt;p&gt;How accurate are these views?&lt;/p&gt;

&lt;p&gt;And how correctable are their mistakes?&lt;/p&gt;

&lt;p&gt;These questions are not merely an idle curiosity. How students
perceive performance impacts how they think about program design
(e.g., they may think a particular design is better but still not use
it because they think it’s less performant). It also affects their
receptiveness to new programming languages and styles (“paradigms”) of
programming. Anecdotally, we have seen exactly these phenomena at play
in our courses.&lt;/p&gt;

&lt;p&gt;We are especially interested in students who have had prior computer
science (in secondary school), such as students taking the AP Computer
Science exam in the US. These students often have significant prior
computing, but we have studied relatively little about the downstream
consequences of these courses. Indeed, performance considerations are
manifest in material as early as the age 4–8 curriculum from Code.org!&lt;/p&gt;

&lt;p&gt;This paper takes a first step in examining these issues. We find that
students have high confidence in incorrect answers on material they
should have little confidence about. To address these problems, we try
multiple known techniques from the psychology and education literature
— the Illusion of Explanatory Depth, and Refutation Texts — that have
been found to work in several other domains. We see that they have
little impact here.&lt;/p&gt;

&lt;p&gt;This work has numerous potential confounds based on the study design
and location of performance. Therefore, we don’t view this as a
definitive result, but rather as a spur to start an urgently-needed
conversation about factors that affect post-secondary computer science
education. Concretely, as we discuss in the discussion sections, we
also believe there is very little we know about how students conceive
of “performance”, and question whether our classical methods for
approaching it are effective.&lt;/p&gt;

&lt;p&gt;The paper is split into a short paper, that summarizes the results,
an an extensive appendix, which provides all the details and justifies
the summary. Both are
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/kbls-prob-persist-perf-precon/&quot;&gt;available online&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Structural Versus Pipeline Composition of Higher-Order Functions</title>
   <link href="http://blog.brownplt.org/2022/08/16/struct-pipe-comp.html"/>
   <updated>2022-08-16T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2022/08/16/struct-pipe-comp</id>
   <content type="html">&lt;p&gt;Building on our
&lt;a href=&quot;/2021/07/31/behavioral-hof.html&quot;&gt;prior work&lt;/a&gt;
on behavioral conceptions of higher-order functions (HOFs),
we have been looking now at their composition. In designing
&lt;a href=&quot;/2022/07/09/plan-comp-hof.html&quot;&gt;a study&lt;/a&gt;,
we kept running into tricky problems in &lt;em&gt;designing HOF
composition problems&lt;/em&gt;. Eventually, we set out to study that question
directly.&lt;/p&gt;

&lt;p&gt;We’re going to give you a quiz. Imagine you have a set of standard
HOFs (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;filter&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sort&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;andmap&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ormap&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;take-while&lt;/code&gt;). You
are given two ways to think about composing them (where “funarg” is
short for the parameter that is a function):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type A&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HOF_A(&amp;lt;some funarg&amp;gt;, HOF_B(&amp;lt;some funarg&amp;gt;, L))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type B&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HOF_C((lambda (inner) HOF_D(&amp;lt;some funarg&amp;gt;, inner)), L)&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Which of these would you consider “easier” for students to
understand and use?&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;How would you rate their relative expressive power in terms of
problems they can solve?&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Don’t go on until you’ve committed to answers to these questions.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Rather than &lt;strong&gt;A&lt;/strong&gt; and &lt;strong&gt;B&lt;/strong&gt;, here are better names: we’ll refer to &lt;strong&gt;A&lt;/strong&gt;
as &lt;em&gt;pipeline&lt;/em&gt;, because it corresponds to a traditional
data-processing/Unix pipeline composition (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HOF_B L | HOF_A&lt;/code&gt;), and
we’ll refer to &lt;strong&gt;B&lt;/strong&gt; as &lt;em&gt;structural&lt;/em&gt;. If you’re like many other people
we’ve asked, you likely think that pipeline is easier, but you’re less
certain about how to answer the second question.&lt;/p&gt;

&lt;p&gt;Alright, now you’re ready to read
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/rk-struct-pipe-comp-hof/&quot;&gt;the paper&lt;/a&gt;! We think the structural/pipeline distinction is
similar to the structural/generative recursion distinction in
&lt;a href=&quot;https://htdp.org/&quot;&gt;HtDP&lt;/a&gt;, and similarly has consequences for how we
order HOF composition in our pedagogy. We discuss all this, and more,
in the document.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Plan Composition Using Higher-Order Functions</title>
   <link href="http://blog.brownplt.org/2022/07/09/plan-comp-hof.html"/>
   <updated>2022-07-09T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2022/07/09/plan-comp-hof</id>
   <content type="html">&lt;p&gt;There is a long history of wanting to examine planning in computing
education research, but relatively little work on it. One problem you
run into when trying to do this seriously is: “What language shall we
use to express plans?” A lot hinges on this language.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;The programming language itself is too low-level: there are too many
administrative details that get in the way and might distract the
student; failures may then reflect these distractions,
not an inability to plan.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Plain English may be too high-level. It’s both difficult to give any
useful (automated) feedback about, it may also require too much
interpretation. In particular, an expert may interpret student
utterances in ways the student didn’t mean, thereby giving the
student an OK signal when in fact the student is not on the right
path.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Separately,
in &lt;a href=&quot;/2021/07/31/behavioral-hof.html&quot;&gt;prior work&lt;/a&gt;,
we looked at whether students are able to understand
higher-order functions (HOFs) from a behavioral perspective: i.e., as
atomic units of behavior without reference to their underlying
implementation. For our population, we found that they generally did
quite well.&lt;/p&gt;

&lt;p&gt;You may now see how these dovetail. Once students have a behavioral
understanding of individual HOFs, you can use them as a starting
&lt;em&gt;vocabulary for planning&lt;/em&gt;. Or to think in more mechanical terms, we
want to study how well students understand the
&lt;em&gt;composition&lt;/em&gt; of HOFs. That is the subject of this work.&lt;/p&gt;

&lt;p&gt;Concretely, we start by confirming our previous result—that they
understand the building blocks—and can also articulate many of the
features that we previously handed out to them. This latter step is
important because any failures at composition may lie in their
insufficiently rich understanding of the functions. Fortunately, we
see that this is again not a problem with our population.&lt;/p&gt;

&lt;p&gt;We then focus on the main question: can they compose these HOFs. We do
this in two ways:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;We give them input-output examples and ask them to identify which
compositions of functions would have produced those results. This
is akin to having a dataset you need to transform and knowing what
you would like the result to look like, and figuring out what steps
will take it there.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We give them programming problems to solve, and ask them to first
provide high-level &lt;em&gt;plans&lt;/em&gt; of their solutions.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What we find is that students don’t do superbly on (1), but do
extremely well on (2). Indeed, our goal had been to study what changes
between the planning and programming phase (e.g., if they planned
incorrectly but programmed correctly; or vice versa), but our students
unfortunately did too well on both to give us any useful data!&lt;/p&gt;

&lt;p&gt;Of particular interest is how we got them to state plans.
While HOFs are the “semantics”, we still need a “syntax” for writing
them. Conventional textual programming has various bad
affordances. Instead, we created a
custom palette of operations in
&lt;a href=&quot;https://snap.berkeley.edu/&quot;&gt;Snap!&lt;/a&gt;. In keeping with the point of this
paper, the operations were HOFs. There are numerous advantages to this
use of Snap!:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Drag-and-drop construction avoids getting bogged down in the
vagaries of textual syntax.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Changing plans is much easier, because you can drag whole blocks and
(again) not get caught up in messy textual details. This means
students are hopefully more willing to change around their plans.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The planning operations focus on the operations we care about, and
students can ignore irrelevant details.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Most subtly: the blanks can be filled in with &lt;strong&gt;text&lt;/strong&gt;. That is, you
get “operations on the outside, text on the inside”: at the point
where things get too detailed, students can focus on presenting
their ideas rather than on low-level details. This is, in other
words, a hybrid of the two methods we suggested at the beginning.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Critically, these aren’t programs! Because of the text, they can’t be
executed. But that’s okay! They’re only meant to help students think
through their plans before starting to write the program. In
particular, given students’ reluctance to change their programs much
once they start coding, it seems especially important to give them a
fluid medium—where switching costs are low—in which to plan things
before they start to write a line of code. So one of the best things
about this paper, beyond the main result, is actually our discovery of
Snap!’s likely utility in this setting.&lt;/p&gt;

&lt;p&gt;For more details, see
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/rkg-plan-comp-use-hof/&quot;&gt;the paper&lt;/a&gt;!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Towards a Notional Machine for Runtime Stacks and Scope</title>
   <link href="http://blog.brownplt.org/2022/07/07/stacks-dont-stack-up.html"/>
   <updated>2022-07-07T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2022/07/07/stacks-dont-stack-up</id>
   <content type="html">&lt;p&gt;Stacks are central to our understanding of program behavior; so is
scope. These concepts become ever more important as ever more
programming languages embrace concepts like closures and advanced
control (like generators). Furthermore, stacks and scope interact in
an interesting way, and these features really exercise their
intersection.&lt;/p&gt;

&lt;p&gt;Over the years we’ve seen students exhibit several problematic
conceptions about stacks (and scope). For instance, consider a program
like this:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;def f(x):
  return g(x + 1)

def g(y):
  return y + x

f(3)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;What is its value? You want an error: that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; is not bound. But think
about your canonical stack diagram for this program. You have a frame
for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;g&lt;/code&gt; atop that for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt;, and you have been told that you “look down
the stack”. (Or vice versa, depending on how your stacks grow.) So
it’s very reasonable to conclude that this program produces &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;7&lt;/code&gt;, the
result produced by dynamic scope.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We see students thinking exactly this.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Consider this program:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;def f(x):
  return lambda y: x + y

p = f(3)

p(4)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This one, conversely, &lt;em&gt;should&lt;/em&gt; produce &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;7&lt;/code&gt;. But students who have been
taught a conventional notion of call-and-return assume that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt;’s
stack frame has been removed after the call completed (correct!), so
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p(4)&lt;/code&gt; must result in an error that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; is not bound.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We see students thinking exactly this, too.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The paper sets out to do several things.&lt;/p&gt;

&lt;p&gt;First, we try to understand the conceptions of stacks that students
have coming into an upper-level programming languages course. (It’s
not great, y’all.)&lt;/p&gt;

&lt;p&gt;Second, we create some tooling to help students learn more about
stacks. More on that below. The tooling seems to work well for
students who get some practice using it.&lt;/p&gt;

&lt;p&gt;Third, we find that even after several rounds of direct instruction
and practice, some misconceptions remain. In particular, students do
not properly understand how environments chain to get scope right.&lt;/p&gt;

&lt;p&gt;Fourth, in a class that had various interventions &lt;em&gt;including&lt;/em&gt;
interpreters, students did much better than in a class where students
learned from interpreters &lt;em&gt;alone&lt;/em&gt;. Though we love interpreters and
think they have various valuable uses in programming languages
education, our results make us question some of the community’s
beliefs about the benefits of using interpreters. In particular, some
notions of transfer that we would have liked to see do not occur. We
therefore believe that the use of interpreters needs much more
investigation.&lt;/p&gt;

&lt;p&gt;As for the tooling: One of the things we learned from our initial
study is that students simply do not have a standardized way of
presenting stacks. What goes in them, and how, were all over the
map. We conjecture there are many reasons: students mostly &lt;em&gt;see&lt;/em&gt;
stacks and are rarely asked to draw them; and when they do, they have
no standard tools for doing so. So they invent various ad hoc
notations, which in turn don’t necessarily reinforce all the aspects
that a stack should represent.&lt;/p&gt;

&lt;p&gt;We therefore created a small tool for drawing stacks. What we did was
repurpose &lt;a href=&quot;https://snap.berkeley.edu/&quot;&gt;Snap!&lt;/a&gt; to create a palette of
stack, environment, and heap blocks. It’s important to understand
these aren’t runnable programs: these are just static representations
of program &lt;strong&gt;states&lt;/strong&gt;. But Snap! is fine with that. This gave us a
consistent notation that we could use everywhere: in class, in the
textbook, and in homeworks. The ability to make stacks very quickly
with drag-and-drop was clearly convenient to students who gained
experience with the tool, because many used it voluntarily; it was
also a huge benefit for in-class instruction over a more conventional
drawing tool. An unexpected success for block syntaxes!&lt;/p&gt;

&lt;p&gt;For more details, see
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/ck-nm-stacks/&quot;&gt;the paper&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Gradual Soundness: Lessons from Static Python</title>
   <link href="http://blog.brownplt.org/2022/06/28/static-python.html"/>
   <updated>2022-06-28T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2022/06/28/static-python</id>
   <content type="html">&lt;p&gt;It is now virtually a truism that every dynamic language adopts a
gradual static type system. However, the space of gradual typing is
vast, with numerous tradeoffs between expressiveness, efficiency,
interoperability, migration effort, and more.&lt;/p&gt;

&lt;p&gt;This work focuses on the Static Python language built by the Instagram
team at Meta. Static Python is an interesting language in this space
for several reasons:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;It is designed to be sound.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It is meant to run fast.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It is reasonably expressive.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The static type system is a combination of what the literature calls
&lt;em&gt;concrete&lt;/em&gt; and &lt;em&gt;transient&lt;/em&gt; types. Concrete types provide full
soundness and low performance overhead, but impose nonlocal
constraints. Transient types are sound in a shallow sense and easier
to use; they help to bridge the gap between untyped code and typed
concrete code. The net result is a language that is in active use,
with high performance, inside Meta.&lt;/p&gt;

&lt;p&gt;Our work here is to both formalize and assess the language. We
investigate the language’s soundness claims and report on its
performance on both micro-benchmarks and in production systems. In
particular, we find that the design holds up the intent of soundness
well, but the act of modeling it uncovered several bugs (including one
that produced a segmentation fault), all of which have now been fixed.&lt;/p&gt;

&lt;p&gt;We believe Static Python is a particularly interesting language for
the gradual typing community to study. It is not based on virtuoso
theoretical advances; rather, it takes solid ideas (e.g., from
Muehlboeck and Tate’s &lt;a href=&quot;https://rosstate.org/publications/nomalive/&quot;&gt;Nom language&lt;/a&gt;),
combines them well, and pays attention to the various affordances needed by
practicing programmers. It therefore offers useful advice to the
designers of other gradually-typed languages, in particular those who
confront large code-bases and would like incremental approaches to
transition from dynamic safety to static soundness. You can read much
more about this
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/lgmvpk-static-python/&quot;&gt;in the paper&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As an aside, this paper is a collaboration that was born entirely
thanks to Twitter and most probably would never have occurred withtout
it. An aggrieved-sounding post by Guido van Rossum led to an
&lt;a href=&quot;https://twitter.com/carljm/status/1393343926564581376&quot;&gt;exchange between&lt;/a&gt;
Carl Meyer at Meta and Shriram, which continued some time later
&lt;a href=&quot;https://twitter.com/carljm/status/1393366892358758402&quot;&gt;here&lt;/a&gt;.
Eventually they moved to Direct Messaging. Shriram pointed out that
&lt;a href=&quot;https://twitter.com/ShriramKMurthi/status/1393354662162669572&quot;&gt;Ben Greenman could investigate this further&lt;/a&gt;,
and from that, this collaboration was born.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Applying Cognitive Principles to Model-Finding Output</title>
   <link href="http://blog.brownplt.org/2022/04/26/pos-val-neg-info.html"/>
   <updated>2022-04-26T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2022/04/26/pos-val-neg-info</id>
   <content type="html">&lt;p&gt;Model-finders produce output to help users understand the
specifications they have written. They therefore effectively make
assumptions about how these will be processed cognitively, but are
usually unaware that they are doing so. What if we apply known
principles from cognitive science to try to improve the output of
model-finders?&lt;/p&gt;

&lt;h1 id=&quot;model-finding-and-specification-exploration&quot;&gt;Model Finding and Specification Exploration&lt;/h1&gt;

&lt;p&gt;Model-finding is everywhere. SAT and SMT solvers are the canonical
model-finders: given a logical specification, they generate a
satisfying instance (a “model”) or report that it’s impossible. Their
speed and generality have embedded them in numerous back-ends. They
are also used directly for analysis and verification, e.g., through
systems like &lt;a href=&quot;https://alloytools.org/&quot;&gt;Alloy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One powerful modality enabled by tools like Alloy is the &lt;em&gt;exploration&lt;/em&gt;
of specifications. Usually, model-finders are used for &lt;em&gt;verification&lt;/em&gt;:
you have a specification &lt;em&gt;and&lt;/em&gt; some properties about it, and a
verifier tells you whether the properties are satisfied or
not. However, we often don’t have properties; we just want to
understand the consequences of a design. While a conventional verifier
is useless in this setting, model-finders have no problem with it:
they will generate models of the specification that show different
possible ways in which it can be realized.&lt;/p&gt;

&lt;h1 id=&quot;presenting-exploration&quot;&gt;Presenting Exploration&lt;/h1&gt;

&lt;p&gt;The models generated by exploration (or even by verification, where
they are typically &lt;em&gt;counterexamples&lt;/em&gt;) can be presented in several
ways. For many users, the most convenient output is visual. Here, for
instance, is a typical image generated using
the &lt;a href=&quot;https://sterling-js.github.io/&quot;&gt;Sterling&lt;/a&gt; visualizer:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/model-finding-output.png&quot; alt=&quot;Model visualization&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As of this writing, Alloy will let you sequentially view one model at
a time.&lt;/p&gt;

&lt;h1 id=&quot;exploration-for-understanding&quot;&gt;Exploration for Understanding&lt;/h1&gt;

&lt;p&gt;The purpose of showing these models is to gain understanding. It is
therefore reasonable to ask what forms of presentation would be most
useful to enable the most understanding. In
&lt;a href=&quot;/2017/07/01/fmtools-usability.html&quot;&gt;earlier work&lt;/a&gt;
we studied details of how each model is shown. That work is orthogonal
to what we do here.&lt;/p&gt;

&lt;p&gt;Here, we are interested in how many models, and of what kind, should
be displayed. We draw on a rich body of literature in perceptual
psychology going back to seminal work by
&lt;a href=&quot;https://psycnet.apa.org/record/1955-08374-001&quot;&gt;Gibson and Gibson in 1955&lt;/a&gt;.
A long line of work since then has explored several dimensions of
this, resulting in a modern understanding of &lt;strong&gt;contrasting cases&lt;/strong&gt;. In
this work, you don’t show a single result; rather, you show a set of
similar examples, to better help people build models of what they are
seeing. Since our goal is to help people understand a specification
through visual output, it was natural to ask whether any of this
literature could help in our setting.&lt;/p&gt;

&lt;h1 id=&quot;our-study&quot;&gt;Our Study&lt;/h1&gt;

&lt;p&gt;We concretely studied numerous experimental conditions involving
different kinds of contrasting cases, where we show multiple models on
screen at once. Critically, we looked at the use of both &lt;em&gt;positive&lt;/em&gt;
and &lt;em&gt;negative&lt;/em&gt; models. Positive models are what you expect: models of
the specification. In contrast, “negative” models are ones that
&lt;strong&gt;don’t&lt;/strong&gt; model the specification.&lt;/p&gt;

&lt;p&gt;There can, of course, be an infinite number of negative models, most
of which are of no use whatsoever: if I write a specification of a
leader-election protocol, a whale or a sandwich are legitimate
negative models. What we are interested in is “near miss” models, i.e.,
ones that could almost have been models but for a small
difference. Our theory was that showing these models would help a user
better understand the “space” of their model. (In this, we were
inspired by prior work by
&lt;a href=&quot;https://link.springer.com/chapter/10.1007/978-3-662-54494-5_2&quot;&gt;Montaghmi and Rayside&lt;/a&gt;.)&lt;/p&gt;

&lt;h1 id=&quot;our-findings&quot;&gt;Our Findings&lt;/h1&gt;

&lt;p&gt;We study these questions through both crowdsourced and talkaloud
studies, and using both quantitative and qualitative methods. We find
that in this setting, the use of multiple models does not seem to have
been a big win. (Had it been, we would still have to confront the
problem of how to fit all that information onto a screen in the
general case.) The use of negative instances &lt;strong&gt;does&lt;/strong&gt; seem to be
helpful. We also constructed novel modes of output such as where a
user can flip between positive and negative instances, and these seem
especially promising.&lt;/p&gt;

&lt;p&gt;Of course, our findings come with numerous caveats. Rather than think
of our results as in any way definitive, we view this as formative
work for a much longer line of research at the intersection of formal
methods and human-computer interaction. We especially believe there is
enormous potential to apply cognitive science principles in this
space, and our paper provides some very rough, preliminary ideas of
how one might do so.&lt;/p&gt;

&lt;h1 id=&quot;for-more-details&quot;&gt;For More Details&lt;/h1&gt;

&lt;p&gt;You can read about all this
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/dnfk-cog-prin-mod-find-pos-neg/&quot;&gt;in our paper&lt;/a&gt;.
Be warned, the paper is a bit of heavy going! There are a lot of
conditions and lots of experiments and data. But hopefully you can get
the gist of it without too much trouble.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Automated, Targeted Testing of Property-Based Testing Predicates</title>
   <link href="http://blog.brownplt.org/2021/11/24/pbt-revisited.html"/>
   <updated>2021-11-24T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2021/11/24/pbt-revisited</id>
   <content type="html">&lt;p&gt;Property-Based Testing (PBT) is not only a valuable sofware quality
improvement method in its own right, it’s a critical bridge between
traditional software development practices (like unit testing) and
formal specification. We discuss this in our
&lt;a href=&quot;/2021/01/10/property-based-testing.html&quot;&gt;previous work&lt;/a&gt;
on assessing student performance on PBT. In particular, we introduce a
mechanism to investigate how they do by decomposing the property into
a collection of independent sub-properties. This gives us semantic
insight into how students perform: rather than a binary scale, we can
identify specific sub-properties that they may have difficulty with.&lt;/p&gt;

&lt;p&gt;While this preliminary work was very useful, it suffered from several
problems, some of which are not surprising while others became clear
to us only in retrospect. In light of that, our new work makes several
improvements.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;The previous work expected each of the sub-properties to be
&lt;em&gt;independent&lt;/em&gt;. However, this is too strong a requirement. For one,
it masks problems that can lurk in the conjunction of
sub-properties. The other problem is more subtle: when you see a
surprising or intriguing student error, you want to add a
sub-property that would catch that error, so you can generate
statistics on it. However, there’s no reason the new property will
be independent; in fact, it almost certainly won’t be.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Our tests were being generated by hand, with one exception that was
so subtle, we employed Alloy to find the test. Why only once? Why
not use Alloy to generate tests in all situations? And while we’re
at it, why not also use a generator from a PBT framework
(specifically, Hypothesis)?&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;And if we’re going to use both value-based and SAT-based example
generators, &lt;em&gt;why not compare them&lt;/em&gt;?&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This new paper does all of the above. It results in a much more
flexible, useful tool for assessing student PBT performance. Second,
it revisits our previous findings about student performance. Third, it
lays out architectures for PBT evaluation using SAT and a
PBT-generator (specifically Hypothesis). In the process it explains
various engineering issues we needed to address. Fourth, it compares
the two approaches; it also compares how the two approaches did
relative to hand-curated test suites.&lt;/p&gt;

&lt;p&gt;You can read about all this
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/nrsdwk-auto-targ-test-pbt-pred/&quot;&gt;in our paper&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>A Benchmark for Tabular Types</title>
   <link href="http://blog.brownplt.org/2021/11/21/b2t2.html"/>
   <updated>2021-11-21T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2021/11/21/b2t2</id>
   <content type="html">&lt;h1 id=&quot;tables-are-everywhere&quot;&gt;Tables are Everywhere&lt;/h1&gt;

&lt;p&gt;Tables are ubiquitous in the world. Newspapers print tables. Reports
include tables. Even children as young as middle-school work
comfortably with tables. Tables are, of course, also ubiquitous in
programming. Because they provide an easy-to-understand, ubiquitous,
already-parsed format, they are also valuable in programming education
(e.g., &lt;a href=&quot;https://dcic-world.org/&quot;&gt;DCIC&lt;/a&gt; works extensively with tables
before moving on to other compound datatypes).&lt;/p&gt;

&lt;h1 id=&quot;typed-programming-with-tables&quot;&gt;(Typed) Programming with Tables&lt;/h1&gt;

&lt;p&gt;When it comes to programming with tables, we have excellent tools like
relational databases. However, using external databases creates
impedance mismatches, so many programmers like to access tabular data
from directly in the language, rather than construct external
calls. The popularity of language-embedded query has not diminished
with time.&lt;/p&gt;

&lt;p&gt;Programming with tables, however, requires attention to types. Tables
are inherently heterogeneous: each column is welcome to use whatever
type makes most sense. This is all the more so if tables are a part of
the language itself: while external data tend to be limited to
“wire-format” types like numbers and strings, inside the language they
can contain images, functions, other tables, and more. (For instance,
we use all of these in &lt;a href=&quot;https://www.pyret.org/&quot;&gt;Pyret&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;What is the type of a table? To make the output of tabular operations
useful, it can’t be something flat like just &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Table&lt;/code&gt;.  Because tables
are heterogenous, they can’t have just a single type parameter (like
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Table&amp;lt;T&amp;gt;&lt;/code&gt;). It may conceptually make sense to have a type parameter
for each column (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Table&amp;lt;String, Number&amp;gt;&lt;/code&gt;), but real-world tables
can have 17 or 37 columns! Programmers also like to access table
columns by name, not only position. And so on.&lt;/p&gt;

&lt;h1 id=&quot;making-results-comparable&quot;&gt;Making Results Comparable&lt;/h1&gt;

&lt;p&gt;In Spring 2021, we ran
&lt;a href=&quot;https://cs.brown.edu/courses/csci2950-x/2021/&quot;&gt;a seminar&lt;/a&gt;
to understand the state of knowledge of type systems for tables. While
we read several excellent papers, we also came away very frustrated:
authors simply did not seem to agree on what a “table” was or what
operations to support. The result was an enormous degree of
&lt;strong&gt;incommensurability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Therefore, rather than invent Yet Another Tabular Type System, we
decided to take a step back and address the incommensurability
problem. What we need as a community is a shared, baseline
understanding of several aspects of tables. That is what this work
does: create a tables &lt;em&gt;benchmark&lt;/em&gt;. This is not a performance
benchmark, however; rather, it’s an &lt;em&gt;expressivity&lt;/em&gt; and &lt;em&gt;design&lt;/em&gt;
benchmark. We call it &lt;em&gt;B2T2: The Brown Benchmark for Tabular Types&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The benchmark doesn’t spring out of thin air. Rather, we extensively
studied tabular support in widely-used industrial languages/libraries:
R, Python/Pandas, and Julia. To cover educational needs, we also
studied the Pyret-based
&lt;a href=&quot;https://www.bootstrapworld.org/materials/data-science/&quot;&gt;Bootstrap:Data Science&lt;/a&gt;
curriculum. You will notice that all are based on dynamic
languages. (Though Pyret has an optional static type system, it
currently does not support tables in any meaningful manner, so tabular
programming is essentially dynamic.)  This is intentional! If
you start with a typed language, you end up reflecting the
(potentially artificial and overly-restrictive) constraints of that
type system. Rather, it’s healthy to study what programmers (seem to)
want to say and do, filter these for reasonability, and reconcile that
with the needs of static types (like decidability).&lt;/p&gt;

&lt;h1 id=&quot;do-now&quot;&gt;Do Now!&lt;/h1&gt;

&lt;p&gt;What do &lt;em&gt;you&lt;/em&gt; expect to find in a tabular programming benchmark?&lt;/p&gt;

&lt;p&gt;Make a list before you read on!&lt;/p&gt;

&lt;h1 id=&quot;benchmark-components&quot;&gt;Benchmark Components&lt;/h1&gt;

&lt;p&gt;B2T2 has the following parts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;A definition of a table&lt;/strong&gt;. There is actually a large space of
 possibilities here. We’ve chosen a definition that is both broad
 and interesting without being onerous.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Examples of tables&lt;/strong&gt;. Why did we bother to provide these? We do so
 because many type systems may have all sorts of internal
 encodings. They are welcome to do so, but they cannot expect the
 outside world to conform to their representation. Therefore, these
 examples represent the canonical versions of these
 tables. Explaining how these will be converted to the internal
 format is the responsibility of the type system designers.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;An API of table operations&lt;/strong&gt;. This is of course the heart of the
 benchmark. In particular, different papers seem to use different
 subsets of operations. What is unclear is whether the missing
 operations are just as easy as the ones shown; difficult; or even
 impossible. This is therefore a big source of incommensurability.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Example programs&lt;/strong&gt;. Depending on the representation of tables and the
 nature of the type systems and languages, these programs may have
 to be rewritten and may (to some observers) look quite unnatural.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these might be predictable with some thought. There are two more
components that may be a little more surprising:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Erroneous programs&lt;/strong&gt;. In all sophisticated systems, there is a
 trade-off between complexity and explainability. We are disturbed
 by how little discussion there is of error-reporting in the papers
 we’ve read, and think the community should re-balance its
 emphasis. Even those who only care about technical depth (boo!) can take
 solace: there can be rich technical work in explaining errors, too!
 Furthermore, by making errors an explicit component, a team that
 does research into human factors—even if they leave all other
 aspects alone—has a “place to stand” to demonstrate their
 contribution.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;A datasheet&lt;/strong&gt;. To improve commensurability,
 we want authors to tell each other—and their users—in a standard
 format not only what they did but also where the bodies are
 buried.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course, all these parts are interesting even in the absence of
types. We just expect that types will impose the most interesting
challenges.&lt;/p&gt;

&lt;h1 id=&quot;an-open-process&quot;&gt;An Open Process&lt;/h1&gt;

&lt;p&gt;We expect this benchmark to grow and evolve. Therefore, we’ve put our
benchmark in a public repository. You’re welcome to make
contributions: correct mistakes, refine definitions, add features,
provide more interesting examples, etc. You can also contribute
solutions in your favorite language!&lt;/p&gt;

&lt;h1 id=&quot;for-more-details&quot;&gt;For More Details&lt;/h1&gt;

&lt;p&gt;You can read about all this
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/lgk-b2t2/&quot;&gt;in our paper&lt;/a&gt;
and work
&lt;a href=&quot;https://github.com/brownplt/B2T2&quot;&gt;with our repository&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Student Help-Seeking for (Un)Specified Behaviors</title>
   <link href="http://blog.brownplt.org/2021/10/02/examplar-weaknesses.html"/>
   <updated>2021-10-02T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2021/10/02/examplar-weaknesses</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Here’s a &lt;a href=&quot;/2024/01/01/examplar.html&quot;&gt;summary of the full arc&lt;/a&gt;, including later work, of the Examplar project.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Over the years we have done a
&lt;a href=&quot;/2020/01/11/examplar.html&quot;&gt;lot&lt;/a&gt;
of
&lt;a href=&quot;/2020/10/20/examplar.html&quot;&gt;work&lt;/a&gt;
on Examplar, our system for helping students understand the problem &lt;em&gt;before&lt;/em&gt;
they start implementing it. Given that students will even use it voluntarily (perhaps even too much),
it would seem to be a success story.&lt;/p&gt;

&lt;p&gt;However, a full and fair scientific account of Examplar should also examine where it fails.
To that end, we conducted an extensive investigation of all the posts students
made on our course help forum for a whole semester, identified which posts
had to do with problem specification (and &lt;em&gt;under&lt;/em&gt;-specification!), and
categorized how helpful or unhelpful Examplar was.&lt;/p&gt;

&lt;p&gt;The good news is we saw several cases where Examplar had been directly helpful
to students. These should indeed be considered a lower-bound, because the point
of Examplar is to “answer” many questions directly, so they would never even
make it onto the help forum.&lt;/p&gt;

&lt;p&gt;But there is also bad news. To wit:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Students sometimes simply fail to use Examplar’s feedback; is this a shortcoming of the UI, of the training, or something inherent to how students interact with such systems?&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Students tend to overly focus on inputs, which are only a part of the suite of examples.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Students do not transfer lessons from earlier assignments to later ones.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Students have various preconceptions about problem statements, such as imagining functionality not asked for or constraints not imposed.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Students enlarge the specification beyond what was written.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Students sometimes just don’t understand Examplar.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These serve to spur future research in this field, and may also point to the limits of automated assistance.&lt;/p&gt;

&lt;p&gt;To learn more about this work, and in particular to get the points above fleshed out,
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/wk-examplar-unspecified/&quot;&gt;see our paper&lt;/a&gt;!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Adding Function Transformers to CODAP</title>
   <link href="http://blog.brownplt.org/2021/08/22/codap-transformers.html"/>
   <updated>2021-08-22T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2021/08/22/codap-transformers</id>
   <content type="html">&lt;p&gt;CODAP is a wonderful tool for data transformation. However, it also has important limitations, especially from the perspective of our curricula. So we’ve set about addressing them so that we can incorporate CODAP into our teaching.&lt;/p&gt;

&lt;h2 id=&quot;codap&quot;&gt;CODAP&lt;/h2&gt;

&lt;p&gt;We at Brown PLT and
&lt;a href=&quot;https://bootstrapworld.org/&quot;&gt;Bootstrap&lt;/a&gt;
are big fans of
&lt;a href=&quot;https://codap.concord.org/&quot;&gt;CODAP&lt;/a&gt;,
a data-analysis tool from the
&lt;a href=&quot;https://concord.org/&quot;&gt;Concord Consortium&lt;/a&gt;.
CODAP has very pleasant support for working with tables and generating plots, and we often turn to it to perform a quick analysis and generate a graph.&lt;/p&gt;

&lt;p&gt;One of the nice things about CODAP, that sets it apart from traditional spreadsheets, is that the basic unit of space is not a table or spreadsheet but a desktop that can contain several objects on it. A workspace can therefore contain many objects side-by-side: a table, a graph, some text, etc.:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/codap-basic-desktop.png&quot; alt=&quot;View of CODAP desktop with several objects.&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Also, a lot of things in CODAP are done through direct manipulation. This is helpful for younger students, who may struggle with formal programming but can use a GUI to manipulate objects.&lt;/p&gt;

&lt;p&gt;There are many other nice features in CODAP, such as the ability to track a data case cross representations, and so on. We urge you to go try it out! When you launch a new CODAP instance, CODAP will offer you a folder of examples, which can help you get acquainted with it and appreciate its features.&lt;/p&gt;

&lt;h2 id=&quot;whats-not-to-love&quot;&gt;What’s Not to Love?&lt;/h2&gt;

&lt;p&gt;Unfortunately, we don’t love everything about CODAP. We’ll illustrate with an example. To be clear, this is not a bug in CODAP, but rather an important difference of opinion in ease-of-use.&lt;/p&gt;

&lt;p&gt;Let’s say we want to find all the people who are below 50 years of age. In CODAP, there are a few ways to do it, all of which have their issues.&lt;/p&gt;

&lt;p&gt;If you don’t mind being imprecise (which may be okay for a quick data exploration, but isn’t if you want to, say, compute a statistic over the result):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Create a new graph.&lt;/li&gt;
  &lt;li&gt;Drag the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Age&lt;/code&gt; column to the graph.&lt;/li&gt;
  &lt;li&gt;Select all the items that are under 50 using visual inspection. (Depending on how much data you have and their spread, you’ll quite possibly under- and/or over-shoot.)&lt;/li&gt;
  &lt;li&gt;Then do the last few steps below.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you care to get an accurate selection, instead begin with:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;First, add a new column to the original table.&lt;/li&gt;
  &lt;li&gt;Enter a formula for that column (in this case, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Age &amp;lt; 50&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;Obtain a selection of the desired items, which can be done in several different ways, also all with trade-offs:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Sort by that column. Unfortunately, this won’t work if there’s grouping in the table. You’d have to select manually. (Try it. This may be a bit harder than it seems.)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Create a graph as above, but of the &lt;em&gt;new&lt;/em&gt; column. This will give you a clean separation into two values. Manually select all the values in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; column. At least now it will be visually clear if you didn’t select all the right values (if the dataset is not too large).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Remove the formula for the new column. Now drag it to the leftmost end of the table. (If you don’t remove the formula, you’ll get an error!) Now you have all the elements grouped by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt; (and operations performed to one can also be performed to the other).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You’re not done! You still have more steps to go:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If you aren’t already in the table (e.g., if you made a graph), select the table.&lt;/li&gt;
  &lt;li&gt;Click on the “Eye” icon.&lt;/li&gt;
  &lt;li&gt;Choose the “Set Aside Unselected Cases” entry.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that, in most or all of these cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You’ve added a completely superfluous column to your dataset.&lt;/li&gt;
  &lt;li&gt;You may have changed the order of items in your dataset.&lt;/li&gt;
  &lt;li&gt;You’ve lost the ability to see the original data alongside the filtered data.&lt;/li&gt;
  &lt;li&gt;You had to take numerous steps.&lt;/li&gt;
  &lt;li&gt;You had to remember to use the Eye icon for filtering, as opposed to other GUI operations for other tasks.&lt;/li&gt;
  &lt;li&gt;You had to remember where the Eye icon even &lt;em&gt;is&lt;/em&gt;: it’s hidden when a table isn’t selected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But most of all, in every single case:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You had to perform all these operations &lt;strong&gt;manually&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why does this matter? We need data science to be reproducible: we should be able to give others our datasets and scripts so they can re-run them to check that they get the same answer, tweak them so they can check the robustness of our answers, and so on. But when all the operations are done &lt;em&gt;manually&lt;/em&gt;, there’s no “script”, only output. That focuses on answers rather than processes, and is anti-reproducibility.&lt;/p&gt;

&lt;p&gt;In contrast, we think of filtering as a &lt;em&gt;program operation&lt;/em&gt; that we apply to a table to produce a new table, leaving the original intact: e.g., the way it works in
&lt;a href=&quot;https://www.pyret.org/&quot;&gt;Pyret&lt;/a&gt;. This addresses almost all of the issues above.&lt;/p&gt;

&lt;h2 id=&quot;other-pedagogic-consequences&quot;&gt;Other Pedagogic Consequences&lt;/h2&gt;

&lt;p&gt;CODAP had to make certain design choices. They made good choices for some settings: for younger children, in particular, the direct manipulation interface works very nicely. It’s a low floor. However, we feel it’s also a lower-than-we’d-like ceiling. There are many things that the CODAP view of data transformation inhibits:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Making operations explicit, as we noted above.&lt;/li&gt;
  &lt;li&gt;Introducing the idea of &lt;strong&gt;functions&lt;/strong&gt; or &lt;strong&gt;transformations&lt;/strong&gt; of data as objects in their own right, not only as manual operations.&lt;/li&gt;
  &lt;li&gt;Having explicit data-transformation functions also connects to other related school curricula, such as algebra.&lt;/li&gt;
  &lt;li&gt;Saving and naming repeated operations, to learn a bottom-up process of developing abstractions.&lt;/li&gt;
  &lt;li&gt;Examining old and new tables side-by-side.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This last point is especially important. A critical task in data science is performing “what if” analyses. What-if fundamentally means we should be able to perform some operation (the “if” part) and &lt;em&gt;compare&lt;/em&gt; the output (the “what” part). We might even want to look at multiple different scenarios, representing different possible outcomes. But traditional what-if analysis, whether in CODAP or on spreadsheets, often requires you, the human, to remember what has changed, rather than letting the computer do it for you. (Microsoft Excel has limited support to get around this, but its very presence indicates that spreadsheets, traditionally, did &lt;em&gt;not&lt;/em&gt; support what-if analysis—even though that’s how they have often been marketed.)&lt;/p&gt;

&lt;p&gt;Finally, there’s also a subtle consequence to CODAP’s design: derived tables must look substantially similar to their parents. In computing terms, the &lt;em&gt;schema&lt;/em&gt; should be largely the same. That works fine when an operation has little impact on the schema: filtering doesn’t change the schema at all (in principle, though in CODAP you have to add an extra column…), and adding a new column is a conservative extension. But what if you want to perform an operation that results in a radically different schema? For instance, consider the “pivot wider” and “pivot longer” operations when we create
&lt;a href=&quot;https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html&quot;&gt;tidy data&lt;/a&gt;.
The results of those operations have &lt;strong&gt;substantially&lt;/strong&gt; different schemas!&lt;/p&gt;

&lt;h2 id=&quot;introducing-codap-transformers&quot;&gt;Introducing CODAP Transformers&lt;/h2&gt;

&lt;p&gt;In response to this critique, we’ve added a new plugin to CODAP called Transformers:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/codap-plugins-dropdown.png&quot; alt=&quot;CODAP Plugins dropdown showing Transformers entry.&quot; width=&quot;50%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;(This work was done by undergrad trio Paul Biberstein, Thomas Castleman, and Jason Chen.)&lt;/p&gt;

&lt;p&gt;This introduces a new pane that lists several transformation operations, grouped by functionality:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/codap-transformers-pane.png&quot; alt=&quot;Transformers pane.&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For instance, with no more textual programming than before (the formula is the same), we can perform our same example as before, i.e., finding all the people younger than 50:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/codap-filter-age-50.png&quot; alt=&quot;Filtering the People table for Age under 50.&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The result is a &lt;strong&gt;new&lt;/strong&gt; table, which co-exists with the original:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/codap-original-and-filtered.png&quot; alt=&quot;Original and filtered tables.&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The resulting table is just as much a table as the original. For instance, we can graph the ages in the two tables and see exactly the difference we’d expect:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/codap-two-graphs.png&quot; alt=&quot;Graphs of ages in original and filtered tables.&quot; width=&quot;50%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;(Over time, of course, you may build up many tables. The Transformers plugin chooses names based on the operations, to make them easy to tell apart. CODAP also lets you resize, minimize, and delete tables. In practice, we don’t expect users to have more than 3–4 tables up at a time.)&lt;/p&gt;

&lt;h2 id=&quot;saving-transformers&quot;&gt;Saving Transformers&lt;/h2&gt;

&lt;p&gt;We might want to perform the same operation on multiple tables. This is valuable in several contexts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;We create a hand-curated table, with known answers, as a test case to make sure our operations perform what we expect. After confirming this, we want to be sure that we applied the exact &lt;em&gt;same&lt;/em&gt; operation to the real dataset.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We want to perform the same operation to several related datasets: e.g., a table per year.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We might also simply want to give a meaningful name to the operation.&lt;/p&gt;

&lt;p&gt;In such cases, we can use the “Save This Transformer” option at the bottom of the Transformers pane:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/codap-save-this-transformer.png&quot; alt=&quot;Saving a transformer.&quot; width=&quot;50%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Following the programming processes we follow and teach, we naturally want you to think about the Design Recipe steps when saving it because, in programming terms, you’re creating a new function.&lt;/p&gt;

&lt;p&gt;This now creates a new named transformer:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/codap-saved-transformer.png&quot; alt=&quot;Saved transformer.&quot; width=&quot;50%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Every part of this is frozen other than the choice of dataset; it can be applied as many times as you want, to as many datasets as you want. The above use-cases are suggestions, but you can use it however you wish.&lt;/p&gt;

&lt;h2 id=&quot;a-note-on-errors&quot;&gt;A Note on Errors&lt;/h2&gt;

&lt;p&gt;Suppose you try to apply an operation improperly. Say, for instance, you have a table of people that does &lt;em&gt;not&lt;/em&gt; have an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Age&lt;/code&gt; column, and you try to filter people with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Age &amp;lt; 50&lt;/code&gt;. There are at least two choices that Transformers can take:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Allow you to try to perform the operation, and report an error.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Prevent you from even trying by simply not showing tables that are invalid in the drop-down list of tables that the operation can be applied to.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We know &lt;em&gt;exactly&lt;/em&gt; what the programming languages reader reading this is thinking: “You’re going to choose the latter, right? Right?!? PLEASE TELL ME YOU ARE!!!”&lt;/p&gt;

&lt;p&gt;Gentle Reader: we’re not.&lt;/p&gt;

&lt;p&gt;Here’s why we chose not to.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;There’s the messy implementation detail of figuring out exactly &lt;em&gt;when&lt;/em&gt; a table should or shouldn’t be shown in the drop-down. And we’d have to maintain that across changes to the CODAP language. There are no such problems in the dynamic version.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But hey, we’re language implementors, we can figure these things out. Rather, our real reason comes from human factors:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Imagine you’re a teacher with a classroom full of students. A student tries to apply an operation to the wrong table. They probably don’t even &lt;em&gt;realize&lt;/em&gt; that the operation can’t be applied. All they know is that the table doesn’t appear in the list. &lt;em&gt;Their table doesn’t appear in the list!&lt;/em&gt; Their reaction is (perhaps rightly) going to be to raise their hand and say to their teacher, “This tool is broken! It won’t even show me my table!!!” And the teacher, dealing with a whole bunch of students, all in different states, may not immediately realize why the table doesn’t show. Everyone’s frustrated; the student feels stuck, and the teacher may be left feeling inadequate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In contrast, if we just let the operation happen, here’s what the student sees:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/codap-error-age-not-found.png&quot; alt=&quot;Error when `Age` is not present.&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now the student has a pretty good chance of figuring out &lt;em&gt;for themselves&lt;/em&gt; what went wrong: not pulling away the teacher from helping someone else, not blaming the tool, and instead giving themselves a chance of fixing their own problem.&lt;/p&gt;

&lt;p&gt;There’s potentially a broader lesson here about making invalid states unrepresentable. Potentially.&lt;/p&gt;

&lt;h2 id=&quot;many-many-transformers&quot;&gt;Many, Many Transformers!&lt;/h2&gt;

&lt;p&gt;We’ve focused on just one transformation here. There are many more. We even have the pivoting operations for
&lt;a href=&quot;https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html&quot;&gt;tidy data&lt;/a&gt;!
(It would have been wrong to tease you with that up top, otherwise.)&lt;/p&gt;

&lt;p&gt;We even take the what-if part seriously: the Compare Transformer lets you compare numeric and categorical data.
Believe it or not, the categorical comparison operator was actually inspired by prior work we’ve done for many years on comparing
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/fkmt-verif-change-impact-xacml/&quot;&gt;access control policies&lt;/a&gt;,
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/nbfdk-margrave-firewall/&quot;&gt;router configurations&lt;/a&gt;,
and
&lt;a href=&quot;/2015/06/02/flowlog5.html&quot;&gt;SDN programs&lt;/a&gt;
(see also our two brief
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/sk-decl-vict-decl-datacenter/&quot;&gt;position&lt;/a&gt;
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/fkd-emb-pol-eng/&quot;&gt;papers&lt;/a&gt;).
It’s pretty thrilling to see the flow of ideas from security and networking research to data science education in a small but very non-obvious way: the grouping in the categorical output is directly inspired by the multi-terminal decision diagrams of our original Margrave system. For more on this line of work, see our &lt;a href=&quot;/2024/06/27/differential-analysis.html&quot;&gt;blog post&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;examples&quot;&gt;Examples&lt;/h2&gt;

&lt;p&gt;For your benefit, we’ve set up a bunch of pre-built CODAP examples that show you the operations in action:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://codap.concord.org/app/static/dg/en/cert/index.html#shared=https%3A%2F%2Fcfm-shared.concord.org%2FsyNhfww3ThTvdDrmemkh%2Ffile.json&quot;&gt;Building attributes, Filtering, and Updating data&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://codap.concord.org/app/static/dg/en/cert/index.html#shared=https%3A%2F%2Fcfm-shared.concord.org%2FVNrAgxJRrWT3vQf56gMW%2Ffile.json&quot;&gt;Partition&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://codap.concord.org/app/static/dg/en/cert/index.html#shared=https%3A%2F%2Fcfm-shared.concord.org%2FmKwN2j3X97XJb2vbk4sF%2Ffile.json&quot;&gt;Filter, Running Sum, and their interaction&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://codap.concord.org/app/static/dg/en/cert/index.html#shared=https%3A%2F%2Fcfm-shared.concord.org%2F04L6hEjkXDJlOn9HE0t1%2Ffile.json&quot;&gt;Transformers that produce single values&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://codap.concord.org/app/static/dg/en/cert/index.html#shared=https%3A%2F%2Fcfm-shared.concord.org%2Ft2G9dLu0KxN0qCTRhOk0%2Ffile.json&quot;&gt;Reusing saved transformers&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://codap.concord.org/app/static/dg/en/cert/index.html#shared=https%3A%2F%2Fcfm-shared.concord.org%2F2ls8SOxfwpDFxLgnTHjf%2Ffile.json&quot;&gt;Categorical Compare&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://codap.concord.org/app/static/dg/en/cert/index.html#shared=https%3A%2F%2Fcfm-shared.concord.org%2FCv4EBtJwkhpObPRZbTQR%2Ffile.json&quot;&gt;Numerical Compare&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://codap.concord.org/app/static/dg/en/cert/index.html#shared=https%3A%2F%2Fcfm-shared.concord.org%2FEJuh9u3Zxr3Ur2zQWkS1%2Ffile.json&quot;&gt;Pivot operations from tidy data&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;make-your-own&quot;&gt;Make Your Own!&lt;/h2&gt;

&lt;p&gt;As you might have guessed from the examples above, transformers are now part of the official CODAP tool. You can go play with them right now
&lt;a href=&quot;https://codap.concord.org/&quot;&gt;on the CODAP site&lt;/a&gt;. Have fun! Tell us what you learned.&lt;/p&gt;

&lt;h2 id=&quot;thanks&quot;&gt;Thanks&lt;/h2&gt;

&lt;p&gt;Special thanks to our friends at the Concord Consortium, especially William Finzer, Jonathan Sandoe, and Chad Dorsey, for their support.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Developing Behavioral Concepts of Higher-Order Functions</title>
   <link href="http://blog.brownplt.org/2021/07/31/behavioral-hof.html"/>
   <updated>2021-07-31T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2021/07/31/behavioral-hof</id>
   <content type="html">&lt;p&gt;Higher-Order Functions (HOFs) are an integral part of the programming
process. They are so ubiquitous,
&lt;a href=&quot;https://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html&quot;&gt;even Java&lt;/a&gt;
had to bow and accept
them. They’re especially central to cleanly expressing the stages of
processing data, as the R community and others have discovered.&lt;/p&gt;

&lt;p&gt;How do we &lt;em&gt;teach&lt;/em&gt; higher-order functions? In some places, like
&lt;a href=&quot;https://htdp.org/&quot;&gt;&lt;em&gt;How to Design Programs&lt;/em&gt;&lt;/a&gt;,
HOFs are presented as &lt;em&gt;abstractions over common patterns&lt;/em&gt;. That is,
you see a certain pattern of program behavior over and over, and
eventually learn to parameterize it and call it &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;filter&lt;/code&gt;, and
so on. That is a powerful method.&lt;/p&gt;

&lt;p&gt;In this work, we take a different perspective. Our students often
&lt;a href=&quot;/2024/01/01/examplar.html&quot;&gt;write examples first&lt;/a&gt;,
so they can think in terms of the behavior they want to achieve. Thus,
they need to develop an understanding of HOFs as &lt;em&gt;abstractions over
common behaviors&lt;/em&gt;: “mapping”, “filtering”, etc.&lt;/p&gt;

&lt;p&gt;Our goal in this work is to study how well students form behavioral
abstractions having been taught code pattern abstractions. Our main
instrument is sets of input-output behavior, such as&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(list &quot;red&quot; &quot;green&quot; &quot;blue&quot;)
--&amp;gt;
(list 3 5 4)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;(Hopefully that calls to mind “mapping”.) We very carefully
designed a set of these to capture various specific similarities,
overlaps, and impossibilities.&lt;/p&gt;

&lt;p&gt;We then evaluated students using two main devices, inspired by
activities in machine learning:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Clustering&lt;/strong&gt;: Group behaviors into clusters of similar ones.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Classification&lt;/strong&gt;: For each behavior, assign a label.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also tried labeling over visual presentations.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/kf-devel-beh-concept-hofs/&quot;&gt;Our paper&lt;/a&gt;
describes these instruments in detail, and our
outcomes. What is most interesting, perhaps, is not our specific
outcomes, but this style of thinking about teaching HOFs. We think the
materials—especially the input-output pairs, and a table of
properties—will be useful to educators who are tackling this
topic. More broadly, we think there’s a huge unexplored space of HOF
pedagogy combined with meaningful evaluation. We hope this work
inspires more work along these lines.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Adversarial Thinking Early in Post-Secondary Education</title>
   <link href="http://blog.brownplt.org/2021/07/18/early-adversarial.html"/>
   <updated>2021-07-18T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2021/07/18/early-adversarial</id>
   <content type="html">&lt;p&gt;Adversarial Thinking (AT) is often described as “thinking like a
hacker” or as a “security mindset”. These quasi-definitions are not
only problematic in their own right (in some cases, they can be
outright circular), they are also too narrow. We believe that AT
applies in many other settings as well: in finding ways where machine
learning can go wrong, for identifying problems with user interfaces,
and for that matter even in software testing and verification.&lt;/p&gt;

&lt;p&gt;All these are, however, quite sophisticated computer science
concepts. Does that mean AT can only be covered in advanced computer
science courses—security, machine learning, formal methods, and the
like? Put differently, how much technical sophistication do students
need before they can start to engage in it?&lt;/p&gt;

&lt;p&gt;We believe AT can be covered starting from a fairly early stage. In
this work, we’ve studied its use with (accelerated) introductory
post-secondary (university) students. We find that they do very well,
but also exhibit some weaknesses. We also find that they are able to
reckon with the consequences of systems well beyond their technical
capability. Finally, we find that they focus heavily on social issues,
not just on technical ones.&lt;/p&gt;

&lt;p&gt;In addition to these findings, we have also assembled a rich set of
materials covering several aspects of computer science. Students
generally found these engaging and thought-provoking, and responded to
them with enthusiasm. We think educators would benefit greatly from
this collection of materials.&lt;/p&gt;

&lt;h1 id=&quot;want-to-learn-more&quot;&gt;Want to Learn More?&lt;/h1&gt;

&lt;p&gt;If you’re interested in this, and in the outcomes,
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/yk-early-ps-perf-stud-adv-think/&quot;&gt;please see our paper&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Teaching and Assessing Property-Based Testing</title>
   <link href="http://blog.brownplt.org/2021/01/10/property-based-testing.html"/>
   <updated>2021-01-10T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2021/01/10/property-based-testing</id>
   <content type="html">&lt;p&gt;Property-Based Testing (PBT) sees increasing use in industry, but lags
significantly behind in education. Many academics have never even
heard of it. This isn’t surprising; computing education still hasn’t
come to terms with even basic software testing,
&lt;a href=&quot;/2024/01/01/examplar.html&quot;&gt;even when it can address pedagogic problems&lt;/a&gt;.
So this lag is predictable.&lt;/p&gt;

&lt;h1 id=&quot;the-problem-of-examples&quot;&gt;The Problem of Examples&lt;/h1&gt;

&lt;p&gt;But even people who want to use it often struggle to find good
examples of it.
Reversing a list
&lt;a href=&quot;https://twitter.com/DRMacIver/status/1140615803752079360&quot;&gt;drives people to drink&lt;/a&gt;,
and math examples
&lt;a href=&quot;https://twitter.com/b0rk/status/1190471160414326785&quot;&gt;are hard to relate to&lt;/a&gt;.
This is a problem from several respects.  Without compelling examples,
nobody will want to teach it.  Even if they do, unless the examples
are compelling, students will not pay attention to it. And if the
students don’t, they won’t recognize opportunities to use it later in
their careers.&lt;/p&gt;

&lt;p&gt;This loses much more than a testing technique. We consider PBT a
gateway to &lt;em&gt;formal specification&lt;/em&gt;. Like a formal spec, it’s an
abstract statement about behaviors. Unlike a formal spec, it doesn’t
require learning a new language or mathematical formalism, it’s
executable, and it produces concrete counter-examples. We therefore
use it, in Brown’s Logic for Systems course, as the starting point to
more formal specifications. (If they learn nothing about formal
specification but simply become better testers, we’d still consider
that a win.)&lt;/p&gt;

&lt;p&gt;Therefore, for the past 10 years, and with growing emphasis, we’ve
been teaching PBT: starting in our accelerated introductory course, then
in Logic for Systems, and gradually in other courses as well. But how
do we motivate the concept?&lt;/p&gt;

&lt;h1 id=&quot;relational-problems&quot;&gt;Relational Problems&lt;/h1&gt;

&lt;p&gt;We motivate PBT through what we call &lt;em&gt;relational&lt;/em&gt; problems. What are
those?&lt;/p&gt;

&lt;p&gt;Think about your typical unit test. You write an input-output
pair: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f(x) is y&lt;/code&gt;. Let’s say it fails:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Usually, the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt; is wrong. Congrats, you’ve just caught a bug!&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Sometimes, the test is wrong: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f(x)&lt;/code&gt; is not, in fact, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt;. This can
take some reflection, and possibly reveals a misunderstanding of the
problem.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s usually where the unit-testing story ends. However, there is
one more possibility:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Neither is “wrong”. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f(x)&lt;/code&gt; has multiple legal results, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;w&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt;, and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z&lt;/code&gt;; your test chose &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt;, but this particular implementation
happened to return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;w&lt;/code&gt; instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We call these “relational” because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt; is clearly more a relation than
a function.&lt;/p&gt;

&lt;h1 id=&quot;some-examples&quot;&gt;Some Examples&lt;/h1&gt;

&lt;p&gt;So far, so abstract. But many problems in computing actually have a
relational flavor:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Consider computing shortest paths in a graph or network; there can
be &lt;em&gt;many&lt;/em&gt; shortest paths, not just one. If we write a test to check
for one particular path, we could easily run into the problem
above.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Many other graph algorithms are also relational. There are many
legal answers, and the implementation happens to pick just one of
them.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Non-deterministic data structures inspire relational
behavior.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Various kinds of matching problems—e.g., the stable-marriage
problem—are relational.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Combinatorial optimization problems are relational.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Even sorting, when done over non-atomic data, is relational.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, computing is full of relational problems. While they are not
at all the only context in which PBT makes sense, they certainly
provide a rich collection of problems &lt;em&gt;that students already study&lt;/em&gt;
that can be used to expose this idea in a non-trivial setting.&lt;/p&gt;

&lt;h1 id=&quot;assessing-student-performance&quot;&gt;Assessing Student Performance&lt;/h1&gt;

&lt;p&gt;Okay, so we’ve been having students write PBT for several years
now. But how well do they do? How do we go about measuring such a
question? (Course grades are far too coarse, and even assignment
grades may include various criteria—like code style—that are not
strictly germane to this question.) Naturally, their core product is
a binary classifier—it labels a purported implementation as valid
or invalid—so we could compute precision and recall. However, these
measures still fail to offer any &lt;em&gt;semantic&lt;/em&gt; insight
into how students did and what they missed.&lt;/p&gt;

&lt;p&gt;We therefore created a new framework for assessing this. To wit, we
took each problem’s abstract property statement (viewed as a formal
specification), and sub-divided it into a &lt;em&gt;set of sub-properties whose
conjunction is the original property&lt;/em&gt;. Each sub-property was then
turned into a test suite, which accepted those validators that
enforced the property and rejected those that did not. This let us get
a more fine-grained understanding of how students did, and what kinds
of mistakes they made.&lt;/p&gt;

&lt;h1 id=&quot;want-to-learn-more&quot;&gt;Want to Learn More?&lt;/h1&gt;

&lt;p&gt;If you’re interested in this, and in the outcomes,
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/wnk-use-rel-prob-pbt/&quot;&gt;please see our paper&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id=&quot;whats-next&quot;&gt;What’s Next?&lt;/h1&gt;

&lt;p&gt;The results in this paper are interesting but preliminary. Our
&lt;a href=&quot;/2021/11/24/pbt-revisited.html&quot;&gt;follow-up work&lt;/a&gt;
describes limitations to the approach presented here, thereby
improving the quality of evaluation, and also innovates in the
generation of classifying tests. Check it out!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Students Testing Without Coercion</title>
   <link href="http://blog.brownplt.org/2020/10/20/examplar.html"/>
   <updated>2020-10-20T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2020/10/20/examplar</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Here’s a &lt;a href=&quot;/2024/01/01/examplar.html&quot;&gt;summary of the full arc&lt;/a&gt;, including later work, of the Examplar project.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It is practically a trope of computing education that students are over-eager to implement, yet woefully under-eager to confirm they understand the problem they are tasked with, or that their implementation matches their expectations. We’ve heard this stereotype couched in various degrees of cynicism, ranging from “students &lt;em&gt;can’t&lt;/em&gt; test” to “students &lt;em&gt;won’t&lt;/em&gt; test”. We aren’t convinced, and have, for several years now, experimented with &lt;em&gt;nudging&lt;/em&gt; students towards early example writing and thorough testing.&lt;/p&gt;

&lt;p&gt;We’ve blogged &lt;a href=&quot;/2020/01/11/examplar.html&quot;&gt;previously&lt;/a&gt; about our prototype IDE, Examplar — our experiment in encouraging students to write illustrative examples for their homework assignments &lt;em&gt;before&lt;/em&gt; they actually dig into their implementation. Examplar started life as a separate, complementary tool from Pyret’s &lt;a href=&quot;https://code.pyret.org/editor&quot;&gt;usual&lt;/a&gt; programming environment, providing a buffer &lt;em&gt;just&lt;/em&gt; for the purposes of developing a test suite. Clicking &lt;strong&gt;Run&lt;/strong&gt; in Examplar runs the student’s test suite against &lt;em&gt;our&lt;/em&gt; implementations (not theirs) and then reports the degree to which the suite was &lt;em&gt;valid&lt;/em&gt; and &lt;em&gt;thorough&lt;/em&gt; (i.e., good at catching our buggy implementations). With this tool, students could catch their misconceptions &lt;em&gt;before&lt;/em&gt; implementing them.&lt;/p&gt;

&lt;p&gt;Although usage of this tool was voluntary for all but the first assignment, students relied on it extensively throughout the semester and the quality of final submissions &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/wk-examplar/&quot;&gt;improved drastically&lt;/a&gt; compared to prior offerings of the course. Our positive with this prototype encouraged us to &lt;em&gt;fully-integrate&lt;/em&gt; Examplar’s feedback into students’ development environment. Examplar’s successor provides a unified environment for the development of &lt;em&gt;both&lt;/em&gt; tests and implementation:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/examplar-2019.svg&quot; alt=&quot;Screenshot of Examplar&apos;s Successor&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This new environment — which provides Examplar-like feedback on &lt;em&gt;every&lt;/em&gt; Run — no longer requires that students have the self-awareness to periodically switch to a separate tool. The environment also requires students to first click a “Begin Implementation” button before showing the tab in which they write their implementation.&lt;/p&gt;

&lt;p&gt;This unified environment enabled us to study, for the first time, whether students wrote examples early, relative to their implementation progress. We tracked the maximum test thoroughness students had achieved &lt;em&gt;prior&lt;/em&gt; to each edit-and-run of their implementations file. Since the IDE notified students of their test thoroughness upon each run, and since students could only increase their thoroughness via edits to their &lt;em&gt;tests&lt;/em&gt; file, the mean of these scores summarizes how thoroughly a student explored the problem with tests &lt;em&gt;before&lt;/em&gt; fully implementing it.&lt;/p&gt;

&lt;p&gt;We find that nearly every student on nearly every assignment achieves some level of thoroughness &lt;em&gt;before&lt;/em&gt; their implementation work:&lt;/p&gt;
&lt;figure&gt;
&lt;a href=&quot;/img/average-thoroughness.svg&quot;&gt;&lt;img src=&quot;/img/average-thoroughness.svg&quot; alt=&quot;The Mean Implementation-Interval Thoroughness of students on various assignments.&quot; width=&quot;100%&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;
The &quot;Mean Implementation-Interval Thoroughness&quot; of each student, on various assignments. (Click picture to open in a new window.)
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;To read more about our design of this environment, its pedagogic context, and our evaluation of students’ development process, &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/wk-stud-write-test-no-coercion/&quot;&gt;check out the full paper here&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Using Design Alternatives to Learn About Data Organizations</title>
   <link href="http://blog.brownplt.org/2020/06/27/data-org.html"/>
   <updated>2020-06-27T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2020/06/27/data-org</id>
   <content type="html">&lt;p&gt;A large number of computer science education papers focus on data
&lt;em&gt;structures&lt;/em&gt;. By this, they mean the canon: lists, queues, stacks,
heaps, and so on. These are certainly vital to the design of most
programs.&lt;/p&gt;

&lt;p&gt;However, there is another kind of “data structure” programmers
routinely contend with: how to represent the world your program is
about. Suppose, for instance, you’re trying to represent a family’s
genealogy. You could:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Represent each person as a node and have references to their two
biological parents, who in turn have references to &lt;em&gt;their&lt;/em&gt;
biological parents, and so on. The tree “bottoms out” when we get to
people about whom we have no more information.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Represent each person as a node and have references to their
&lt;em&gt;children&lt;/em&gt; instead (a list, say, if we want to preserve their birth
order). This tree bottoms out at people who have no children.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Represent each &lt;em&gt;coupling&lt;/em&gt; as a node, and have references to
their children (or &lt;em&gt;issue&lt;/em&gt;, as genealogists like to say). Now you
may have a kind of node for children and another for coupling.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And so on. There are numerous possibilities. Which one should we pick?
It depends on (1) what information we even have, (2) what operations
we want to perform, and (3) what complexity we need different
operations to take.&lt;/p&gt;

&lt;p&gt;Unfortunately, computing education research doesn’t talk about this
problem very much at all; in fact, we don’t seem to even have
terminology to talk about this issue. In a sense, this is also very
much a matter of data &lt;em&gt;structure&lt;/em&gt;, though of a different kind: whereas
the purely abstract data structures of computer science we might call
&lt;em&gt;computational&lt;/em&gt; data structures, these — which center around directly
representing real-world information — we might instead call
&lt;em&gt;representational&lt;/em&gt; data structures. That could get pretty confusing,
though, so we’ve adopted the term &lt;strong&gt;data organization&lt;/strong&gt; to refer to
the latter.&lt;/p&gt;

&lt;p&gt;Learning to think about data organization is an essential computing
skill. But how early can we teach it? How well can students wrestle
with it? What methods should we use? Do they need to be sophisticated
programmers before they can engage in reasoning about representations?&lt;/p&gt;

&lt;p&gt;Good news: we can begin this quite early, and students don’t need to
be sophisticated computer scientists: they can just think about &lt;em&gt;the
world&lt;/em&gt;, and their experiences living in it, to reason about data
organizations. Representational data structures probably do a far
better job of drawing on their lived experience than computational
ones do! (Unless they’ve previously lived as a computer.)&lt;/p&gt;

&lt;p&gt;There are several ways we could introduce this topic. We chose to
expose them to &lt;em&gt;pairs&lt;/em&gt; of representations for the same domain, and
have them &lt;em&gt;compare&lt;/em&gt; the two. This is related to theories of
perception.
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/ghlrfk-design-alt-data-org/&quot;&gt;Read the paper&lt;/a&gt;
to learn more!&lt;/p&gt;

&lt;p&gt;Somewhat subtly, this also adds a dimension to “computational
thinking” that is usually quite missing from standard discussions
about it. Activities like those described in this paper generate new
and engaging activities that many students can participate in. Indeed,
computing background does not seem to matter much in our data, and a
more diverse group of students is likely to make a much richer set of
judgments—thereby enabling students in traditionally underrepresented
groups to contribute based on their unique experiences, and also feel
more valued.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>What Help Do Students Seek in TA Office Hours?</title>
   <link href="http://blog.brownplt.org/2020/05/20/office-hours.html"/>
   <updated>2020-05-20T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2020/05/20/office-hours</id>
   <content type="html">&lt;p&gt;In computer science, a large number of students get help from teaching assistants (TAs). A great deal of their real education happens in these hours. While TA hours are an excellent resource, they are also rather opaque to the instructors, who do not really know what happens in them.&lt;/p&gt;

&lt;p&gt;How do we construct a mechanism to study what happens in hours? It’s actually not obvious at all:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;We could set up cameras to record all the interactions in hours. While this would provide a lot of information, it significantly changes the nature of hours. For many students, hours are private time with a TA, where they can freely speak about their discomfort and get help from a peer; they might ask personal questions; they might also complain about the instructor. One does not install cameras in confessionals.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We could ask TAs to write extensive notes (redacting private information) after the student has left. This also has various flaws:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;Their memory may be faulty.&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Their recollection may be biased by their own beliefs.&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;It would slow down processing students, who already confront overly-long lines and waits.&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What do we instead want? A process that is non-intrusive, lightweight, and yet informative. We have to also give up on perfect knowledge, and focus on information that is actually useful to the instructor.&lt;/p&gt;

&lt;p&gt;Part of the problem is that we as a community lack a systematic method to &lt;em&gt;help&lt;/em&gt; students in the first place. If students have no structure to how they approach help-seeking, then it’s hard to find patterns and make sense of what they actually do.&lt;/p&gt;

&lt;p&gt;However, this is exactly a problem that the &lt;a href=&quot;https://htdp.org/&quot;&gt;&lt;em&gt;How to Design Programs&lt;/em&gt;&lt;/a&gt; Design Recipe was addressed to solve. It provides a systematic way for students to structure their problem-solving and help-seeking. TAs are instructed to focus on the steps of the Design Recipe in order, not addressing later steps until students have successfully completed the earlier ones. This provides an “early warning” diagnostic, addressing root causes rather than their (far-removed) manifestations.&lt;/p&gt;

&lt;p&gt;Therefore, we decided to use the Design Recipe steps as a lens for obtaining insight into TA hours. We argue that this provides a preliminary tool that addresses our needs: it is lightweight, non-intrusive, and yet useful to the instructor. &lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/rkf-student-ta-hours/&quot;&gt;Read the paper&lt;/a&gt;
to learn more!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Combating Misconceptions by Encouraging Example-Writing</title>
   <link href="http://blog.brownplt.org/2020/01/11/examplar.html"/>
   <updated>2020-01-11T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2020/01/11/examplar</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Here’s a &lt;a href=&quot;/2024/01/01/examplar.html&quot;&gt;summary of the full arc&lt;/a&gt;, including later work, of the Examplar project.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When faced with an unfamiliar programming problem, undergraduate computer science students all-too-often begin their implementations with an incomplete understanding of what the problem is asking, and may not realize until far into their development process (if at all) that they have solved the wrong problem. At best, a student realizes their mistake, suffers from some frustration, and is able to correct it before the final submission deadline. At worst, they might not realize their mistake until they receive feedback on their final submission—depriving them of the intended learning goal of the assignment.&lt;/p&gt;

&lt;p&gt;Educators must therefore provide students with some mechanism by which students can evaluate their own understanding of a problem—&lt;em&gt;before&lt;/em&gt; they waste time implementing some misconceived variation of that problem. To this end, we provide students with Examplar: an IDE for writing input–output examples that provides on-demand feedback on whether the examples are:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;em&gt;valid&lt;/em&gt; (consistent with the problem), and&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;thorough&lt;/em&gt; (explore the conceptually interesting corners of the problem).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ofpwTbvG7MA&quot;&gt;For a demonstration, watch this brief video!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With its gamification, we believed students would find Examplar compelling to use. Moreover, we believed its feedback would be helpful. Both of these hypotheses were confirmed. We found that students used Examplar extensively—even when they were not required to use it, and even for assignments for which they were not required to submit test cases. The quality of students’ final submissions generally improved over previous years, too. For more information, &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/wk-examplar/&quot;&gt;read the full paper here&lt;/a&gt;!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Hidden Perils of Automated Assessment</title>
   <link href="http://blog.brownplt.org/2018/07/26/perils-of-automated-assessment.html"/>
   <updated>2018-07-26T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2018/07/26/perils-of-automated-assessment</id>
   <content type="html">&lt;p&gt;We routinely rely on automated assessment to evaluate our students’ work on programming assignments. In principle, these techniques improve the scalability and reproducibility of our assessments. In actuality, these techniques may make it incredibly easy to perform &lt;em&gt;flawed&lt;/em&gt; assessments at scale, with virtually no feedback to warn the instructor. Not only does this affect students, it can also affect the reliability of research that uses it (e.g., that correlates against assessment scores).&lt;/p&gt;

&lt;h3 id=&quot;to-test-a-test-suite&quot;&gt;To Test a Test Suite&lt;/h3&gt;
&lt;p&gt;The initial object of our study was simply to evaluate the quality of student test suites. However, as we began to perform our measurements, we wondered how stable they were, and started to use different methods to evaluate stability.&lt;/p&gt;

&lt;p&gt;In this group, we take the perspective that test suites are &lt;em&gt;classifiers&lt;/em&gt; of implementations. You give a test suite an implementation, and it either &lt;em&gt;accepts&lt;/em&gt; or &lt;em&gt;rejects&lt;/em&gt; it. Therefore, to measure the quality of a test suite, we can standard metrics for classifiers, &lt;em&gt;true positive rate&lt;/em&gt; and &lt;em&gt;true negative rate&lt;/em&gt;. However, to actually do this, we need a set of implementations that we know, &lt;em&gt;a priori&lt;/em&gt;, to be correct or faulty.&lt;/p&gt;

&lt;figure style=&quot;&quot;&gt;
&lt;style&gt;
td { border: 1px grey solid; padding: 0.5em;}
th { padding: 1em;
&lt;/style&gt;
&lt;table style=&quot;border-collapse:collapse; margin: 0 auto&quot;&gt;
  &lt;tr&gt;
    &lt;th style=&quot;visibility:hidden; border: none;&quot;&gt;&lt;/th&gt;
    &lt;th style=&quot;visibility:hidden; border: none;&quot;&gt;&lt;/th&gt;
    &lt;th colspan=&quot;2&quot; style=&quot;text-align:center&quot;&gt;&lt;i&gt;Ground Truth&lt;/i&gt;&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr style=&quot;text-align:center&quot;&gt;
    &lt;td style=&quot;visibility:hidden; border: none;&quot;&gt;&lt;/td&gt;
    &lt;td style=&quot;visibility:hidden; border: none;&quot;&gt;&lt;/td&gt;
    &lt;td&gt;&lt;i&gt;Correct&lt;/i&gt;&lt;/td&gt;
    &lt;td&gt;&lt;i&gt;Faulty&lt;/i&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr style=&quot;text-align:center&quot;&gt;
    &lt;th rowspan=&quot;2&quot;&gt;&lt;i&gt;Test&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Suite&lt;/i&gt;&lt;/th&gt;
    &lt;td&gt;&lt;i&gt;Accept&lt;/i&gt;&lt;/td&gt;
    &lt;td&gt;True Negative&lt;/td&gt;
    &lt;td&gt;False Negative&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;i&gt;Reject&lt;/i&gt;&lt;/td&gt;
    &lt;td&gt;False Positive&lt;/td&gt;
    &lt;td&gt;True Positive&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;/figure&gt;

&lt;p&gt;A robust assessment of a classifier may require a larger collection of known-correct and known-faulty implementations than the instructor could craft themselves. Additionally, we can leverage all of the implementations that students are submitting—we just need to determine which are correct and which are faulty.&lt;/p&gt;

&lt;p&gt;There are basically two ways of doing this in the literature; let’s see how they fare.&lt;/p&gt;

&lt;h3 id=&quot;the-axiomatic-model&quot;&gt;The Axiomatic Model&lt;/h3&gt;

&lt;p&gt;In the first method, the instructor writes a test suite and whatever that test suite’s judgments is used as the ground truth; e.g., if the instructor test suite accepts a given implementation, it is a false positive for a student’s test suite to reject it.&lt;/p&gt;

&lt;h3 id=&quot;the-algorithmic-model&quot;&gt;The Algorithmic Model&lt;/h3&gt;

&lt;p&gt;The second method does this by taking every test suite you have (i.e., both the instructor’s and the students’), running them all against a known-correct implementation, and gluing all the ones that pass it into one big mega test suite that is used to establish ground truth.&lt;/p&gt;

&lt;h2 id=&quot;a-tale-of-two-assessments&quot;&gt;A Tale of Two Assessments&lt;/h2&gt;

&lt;p&gt;We applied each model in turn to classify 38 student implementations and a handful of specially crafted ones (both correct and faulty, in case the student submissions were skewed heavily towards faultiness or correctness), then computed the true-positive and true-negative rate for each student’s test suite.&lt;/p&gt;

&lt;p&gt;The choice of underlying implementation classification model &lt;em&gt;substantially&lt;/em&gt; impacted the apparent quality of student test suites. Visualized as kernel density estimation plots (akin to smoothed histograms):&lt;/p&gt;

&lt;h4 id=&quot;the-axiomatic-model-1&quot;&gt;The Axiomatic Model:&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/img/axiomatic-density.svg&quot; alt=&quot;Plot of test suite performance atop axiomatic classification.&quot; /&gt;
Judging by this plot, students did astoundingly well at catching buggy implementations. Their success at identifying correct implementations was more varied, but still pretty good.&lt;/p&gt;

&lt;h4 id=&quot;the-algorithmic-model-1&quot;&gt;The Algorithmic Model:&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/img/algorithmic-density.svg&quot; alt=&quot;Plot of test suite performance atop algorthmic classification.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Judging by this plot, students performed astoundingly &lt;em&gt;poorly&lt;/em&gt; at detecting buggy implementations, but quite well at identifying correct ones.&lt;/p&gt;

&lt;h2 id=&quot;towards-robust-assessments&quot;&gt;Towards Robust Assessments&lt;/h2&gt;
&lt;p&gt;So which is it? Do students miss half of all buggy implementations, or are they actually astoundingly good? In actuality: neither. These strikingly divergent analysis outcomes are produced by fundamental, theoretical flaws in how these models classify implementations.&lt;/p&gt;

&lt;p&gt;We were alarmed to find that these theoretical flaws, to varying degrees, affected the assessments of &lt;em&gt;every&lt;/em&gt; assignment we evaluated. Neither model provides any indication to warn instructors when these flaws are impacting their assessments. For more information about these perils, see  &lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/wkf-who-tests-testers/&quot;&gt;our paper&lt;/a&gt;, in which we present a technique for instructors and researchers that detects and protects against them.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Mystery Languages</title>
   <link href="http://blog.brownplt.org/2018/07/05/mystery-languages.html"/>
   <updated>2018-07-05T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2018/07/05/mystery-languages</id>
   <content type="html">&lt;p&gt;How do you learn a new language? Do you simply read its reference
manual, and then you’re good to go? Or do you also explore the
language, trying things out by hand to see how they behave?&lt;/p&gt;

&lt;p&gt;This skill—learning about something by poking at it—is frequently used
but almost never taught. However, we have tried to teach it via what
we dub &lt;em&gt;mystery languages&lt;/em&gt;, and this post is about how we went about it.&lt;/p&gt;

&lt;h3 id=&quot;mystery-lanuages&quot;&gt;Mystery Lanuages&lt;/h3&gt;

&lt;p&gt;A &lt;em&gt;mystery language&lt;/em&gt; is exactly what it sounds like: a programming
language whose behavior is a mystery. Each assignment comes with some
vague documentation, and an editor in which you can write programs.
However, when you run a program it will produce multiple answers! This
is because there are actually &lt;em&gt;multiple languages&lt;/em&gt;, with the same
syntax but different semantics. The answers you get are the results of
running your program in all of the different languages. The goal of
the assignment is to find programs that tell the languages apart.&lt;/p&gt;

&lt;p&gt;As an example, maybe the languages have the syntax &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a[i]&lt;/code&gt;, and the
documentation says that this “accesses an array &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a&lt;/code&gt; at index &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt;”.
That totally specifies the behavior of this syntax, right?&lt;/p&gt;

&lt;p&gt;Not even close. For example, what happens if the index is out of bounds?
Does it raise an error (like Java), or return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;undefined&lt;/code&gt; (like
JavaScript), or produce nonsense (like C), or wrap the index to a
valid one (like Python)? And what happens if the index is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2.5&lt;/code&gt;, or
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;2&quot;&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2.0&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;two&quot;&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;(EDIT: Specifically, Python wraps negative indices that are smaller than the length of the array.)&lt;/p&gt;

&lt;p&gt;Students engage with the mystery languages in three ways:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The first part of each assignment is to find a set of programs that
distinguishes the different languages (a.k.a. a &lt;em&gt;classifier&lt;/em&gt;).&lt;/li&gt;
  &lt;li&gt;The second part of the assignment is to describe a &lt;em&gt;theory&lt;/em&gt; that
explains the different behaviors of the languages. (For example, a
theory about C’s behavior could include accessing heap addresses
past the end of an array.)&lt;/li&gt;
  &lt;li&gt;Finally, after an assignment is due, there’s an in-class discussion
and explanation of the mystery languages. This is especially useful
to provide terminology for behaviors that students encountered in
the languages.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This example is somewhat superficial (the real mystery languages
mostly use more significant features than array access), but you get
the idea: every aspect of a programming language comes with many
possible designs, and the mystery languages have students explore
them first-hand.&lt;/p&gt;

&lt;h3 id=&quot;why-mystery-languages&quot;&gt;Why Mystery Languages?&lt;/h3&gt;

&lt;p&gt;We hope to teach a number of skills through mystery languages:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Evaluating Design Decisions:&lt;/strong&gt; The mystery languages are almost
entirely based on designs chosen by real languages: either
historical choices that have since been settled, or choices that are
still up in the air and vary between modern languages. Students get
to explore the consequences of these decisions themselves, so that
they get a feel for them. And the next day in class they learn about
the broader historical context.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Syntax vs. Semantics:&lt;/strong&gt; We are frustrated by how
frequently discussions about programming languages revolve around
syntax. With luck, showing students first-hand that a single syntax
can have a variety of semantics will bring their discussions to a
somewhat higher level.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Adversarial Thinking:&lt;/strong&gt; Notice that the array example was all
about exploring edge cases. If you only ever wrote correct, safe,
boring programs then you’d never notice the different ways that
array access could work. This is very similar to the kind of
thinking you need to do when
&lt;a href=&quot;https://www.schneier.com/blog/archives/2008/03/the_security_mi_1.html&quot;&gt;reasoning about security&lt;/a&gt;,
and we hope that students might pick up on this mindset.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Experimental Thinking:&lt;/strong&gt; In each assignment, students are asked
not only to find programs that behave differently across the mystery
languages, but also to &lt;em&gt;explain&lt;/em&gt; the behavior of the different
languages. This is essentially a scientific task: brainstorm
hypotheses about how the languages might work; experimentally test
these hypotheses by running programs; discard any hypothesis that
was falsified; and iterate.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;adopting-mystery-languages&quot;&gt;Adopting Mystery Languages&lt;/h3&gt;

&lt;p&gt;If you want to use Mystery Languages in your course, email us and
we’ll help you get started!&lt;/p&gt;

&lt;p&gt;There are currently 13 mystery languages, and more in development. At
Brown, we structured our programming languages course around these
mystery languages: about half of the assignments and half of the
lectures were about mystery languages. However, mystery languages are
quite flexible, and could also be used as a smaller supplement to an
existing course. One possibility is to begin with one or two simpler
languages to allow students to learn how they work, and from there mix
and match any of the more advanced languages. Alternatively, you could
do just one or two mystery languages to meet specific course objectives.&lt;/p&gt;

&lt;h3 id=&quot;learn-more&quot;&gt;Learn More&lt;/h3&gt;

&lt;p&gt;You can learn more about mystery languages in
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/pkf-teach-pl-exp-adv-think/&quot;&gt;our SNAPL’17 paper&lt;/a&gt;.
For the latest version of the software,
&lt;a href=&quot;https://github.com/shriram/mystery-languages&quot;&gt;see this repository&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Resugaring Type Rules</title>
   <link href="http://blog.brownplt.org/2018/06/19/resugaring-type-rules.html"/>
   <updated>2018-06-19T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2018/06/19/resugaring-type-rules</id>
   <content type="html">&lt;p&gt;&lt;em&gt;This is the final post in a series about resugaring.
It focuses on resugaring type rules.
See also our posts on
&lt;a href=&quot;/2016/02/06/resugaring.html&quot;&gt;resugaring evaluation steps&lt;/a&gt;
and &lt;a href=&quot;/2017/06/12/scope-inference.html&quot;&gt;resugaring scope rules&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;No one should have to see the insides of your macros. Yet type errors
often reveal them. For example, here is a very simple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;and&lt;/code&gt; macro in
Rust (of course you should just use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt; instead, but we’ll use this
as a simple working example):&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/rust-and-macro.png&quot; style=&quot;width: 400px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;and the type error message you get if you misuse it:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/rust-and-macro-error.png&quot; style=&quot;width: 700px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can see that it shows you the definition of this macro. In this
case it’s not so bad, but other macros can get &lt;em&gt;messy&lt;/em&gt;, and you might
not want to see their guts. Plus in principle, a type error should
only show the erronous code, not correct code that it happend to call.
You wouldn’t be very happy with a type checker that sometimes threw an
error deep in the body of a (type correct) library function that you
called, just because you used it the wrong way. Why put up with one
that does the same thing for macros?&lt;/p&gt;

&lt;p&gt;The reason Rust does is that that it does not know the type of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;and&lt;/code&gt;.
As a result, it can only type check &lt;em&gt;after&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;and&lt;/code&gt; has been desugared
(a.k.a., expanded), and so the error occurs in the desugared code.&lt;/p&gt;

&lt;p&gt;But what if Rust could automatically infer a type rule for checking
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;and&lt;/code&gt;, using only its definition? Then the error could be found in
the original program that you wrote (rather than its expansion), and
presented as such. This is exactly what we did—albeit for simpler type
systems than Rust’s—in our recent PLDI’18 paper
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/pk-resuarging-types/&quot;&gt;Inferring Type Rules for Syntactic Sugar&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We call this process &lt;em&gt;resugaring type rules&lt;/em&gt;, akin to our previous work
on
&lt;a href=&quot;/2016/02/06/resugaring.html&quot;&gt;resugaring evaluation steps&lt;/a&gt;
and
&lt;a href=&quot;/2017/06/12/scope-inference.html&quot;&gt;resugaring scope rules&lt;/a&gt;.
Let’s walk through the resugaring of a type rule for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;and&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/and-desugaring-rule.png&quot; style=&quot;width: 500px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We want to automatically derive a type rule for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;and&lt;/code&gt;, and we want it
to be &lt;em&gt;correct&lt;/em&gt;. But what does it mean for it to be correct? Well, the
meaning of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;and&lt;/code&gt; is defined by its desugaring: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;α and β&lt;/code&gt; is synonymous
with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if α then β else false&lt;/code&gt;. Thus they should have the same type:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/and-formula.png&quot; style=&quot;width: 600px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Isurf ||-&lt;/code&gt; means “in the surface language type system”, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Icore
||-&lt;/code&gt; means “in the core language type system”, and the fancy D means
“desugar”.)&lt;/p&gt;

&lt;p&gt;How can we achieve this? The most straightforward to do is to capture
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iff&lt;/code&gt; with two type rules, one for the forward implication, and
one for the reverse:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/and-rule-forward.png&quot; style=&quot;width: 500px;&quot; /&gt;
&lt;img src=&quot;/img/and-rule-reverse.png&quot; style=&quot;width: 500px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The first type rule is useful because it says how to type check &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;and&lt;/code&gt;
in terms of its desugaring. For example, here’s a derivation that
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true and false&lt;/code&gt; has type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bool&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/and-type-derivation.png&quot; style=&quot;width: 600px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;However, while this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t-and&lt;/code&gt;&lt;sup&gt;→&lt;/sup&gt; rule is accurate, it’s not the canonical
type rule for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;and&lt;/code&gt; that you’d expect. And worse, it mentions &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt;, so
it’s leaking the implementation of the macro!&lt;/p&gt;

&lt;p&gt;However, we can automatically construct a better type rule. The trick
is to look at a more general derivation. Here’s a generic type
derivation for &lt;em&gt;any&lt;/em&gt; term &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;α and β&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/generic-and-type-derivation.png&quot; style=&quot;width: 600px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Notice D&lt;sub&gt;α&lt;/sub&gt; and D&lt;sub&gt;β&lt;/sub&gt;: these are &lt;em&gt;holes&lt;/em&gt; in the derivation, which ought to
be filled in with sub-derivations proving that α has type Bool and β
has type Bool. Thus, “α : Bool” and “β : Bool” are &lt;em&gt;assumptions&lt;/em&gt; we
must make for the type derivation to work. However, &lt;em&gt;if&lt;/em&gt; these
assumptions hold, &lt;em&gt;then&lt;/em&gt; the conclusion of the derivation must hold.
We can capture this fact in a type rule, whole premises are these
assumptions, and whose conclusion is the conclusion of the whole
derivation:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/and-type-rule.png&quot; style=&quot;width: 400px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And so we’ve inferred the canonical type rule for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;and&lt;/code&gt;! Notice that
(i) it doesn’t mention &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; at all, so it’s not leaking the inside of
the macro, and (ii) it’s guaranteed to be correct, so it’s a good
starting point for fixing up a type system to present errors at the
right level of abstraction. This was a simple example for illustrative
purposes, but we’ve tested the approach on a variety of sugars and
type systems.&lt;/p&gt;

&lt;p&gt;You can read more in
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/pk-resuarging-types/&quot;&gt;our paper&lt;/a&gt;,
or
play with &lt;a href=&quot;https://github.com/brownplt/judgmental-resugaring&quot;&gt;the implementation&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Picking Colors for Pyret Error Messages</title>
   <link href="http://blog.brownplt.org/2018/06/11/philogenic-colors.html"/>
   <updated>2018-06-11T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2018/06/11/philogenic-colors</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;pyret.org&quot;&gt;Pyret&lt;/a&gt; has beautiful error messages, like this one:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/pyret-error.png&quot; alt=&quot;Sample Pyret error message&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Notice the colors. Aren’t they pretty? Whenever a section of code is
mentioned in an error message, it gets highlighted with its own color.
And we pick colors that are as different as possible, so they don’t
get confused with each other. It is useful to keep all of the colors
distinct because it provides a very intuitive one-to-one mapping
between parts of the code you wrote and the code snippets mentioned in
the error messages. If two error messages used the same color for a
snippet, it might look at first glance that they were mentioning the
same thing.&lt;/p&gt;

&lt;p&gt;(We should say up front: while we believe that the approach described
in this post should be fairly robust to most forms of color blindness,
it’s difficult to reason about so we make no guarantees. However, if
two colors are hard to distinguish by sight, you can always hover over
one of them to see the matching section of code blink. EDIT: Actually,
it’s not as robust as we had hoped. If you know a good approach to
this, let us know.)&lt;/p&gt;

&lt;p&gt;How did we make them? It should be easy, right? We could have a list
of, say, six colors and use those. After all, no error message needs
more than six colors.&lt;/p&gt;

&lt;p&gt;Except that there might be &lt;em&gt;multiple&lt;/em&gt; error messages. In fact, if you
have failing test cases, then you’ll have one failure message per
failing test case, each with its own highlight, so there is no upper
bound on how many colors we need. (Pyret will only show one of these
highlights at a time—whichever one you have selected—but even so
it’s nice for them to all have different colors.) Thus we’ll need to
be able to &lt;em&gt;generate&lt;/em&gt; a set of colors on demand.&lt;/p&gt;

&lt;p&gt;Ok, so for any given run of the program, we’ll first determine how
many colors we need for that run, and then generate that many colors.&lt;/p&gt;

&lt;p&gt;Except that it’s difficult to tell how many colors we need beforehand.
In fact, Pyret has a REPL, where users can evaluate expressions, which
might throw &lt;em&gt;more&lt;/em&gt; errors. Thus it’s &lt;em&gt;impossible&lt;/em&gt; to know how many
colors we’ll need beforehand, because the user can always produce
&lt;em&gt;more&lt;/em&gt; errors in the REPL.&lt;/p&gt;

&lt;p&gt;Therefore, however we pick colors, it must satisfy these two
properties:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Distinctness&lt;/strong&gt;: all of the colors in all of the highlights should
be as visually different from each other as possible.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Streaming&lt;/strong&gt;: we must always be able to pick new colors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, the appearance of the highlights should be pretty uniform; none
of them should stand out too much:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Uniformity&lt;/strong&gt;: all of the colors should have the same saturation
(i.e. colorfulness) and lightness as each other. This way none of
them blend in with the background color (which is white) or the text
color (which is black), or stand out too much.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;the-phillotactic-color-picking-algorithm&quot;&gt;The &lt;em&gt;Phillotactic&lt;/em&gt; Color-Picking Algorithm&lt;/h3&gt;

&lt;p&gt;Now let’s talk about the algorithm we use!&lt;/p&gt;

&lt;p&gt;(Note that this is “ph&lt;strong&gt;i&lt;/strong&gt;llotactic”, not “&lt;a href=&quot;https://goldenratiomyth.weebly.com/phyllotaxis-the-fibonacci-sequence-in-nature.html&quot;&gt;ph&lt;strong&gt;y&lt;/strong&gt;llotactic&lt;/a&gt;”. It has
nothing to do with plants.)&lt;/p&gt;

&lt;p&gt;To keep uniformity, it makes sense to pick colors from a rainbow. This
is a circle in color space, with constant saturation and lightness and
varying hue. Which color space should we use? We should &lt;em&gt;not&lt;/em&gt; use RGB,
because that space doesn’t agree well with how colors actually appear.
For example, if we used a rainbow in RGB space, then green would
appear far too bright and blue would appear far too dark. Instead, we
should use a color space that agrees with how people actually
perceieve colors. The
&lt;a href=&quot;https://en.wikipedia.org/wiki/CIELAB_color_space&quot;&gt;CIELAB&lt;/a&gt; color space
is better. It was designed so that if you take the distance between
two colors in it, that distance approximately agrees with how
different the colors seem when you look at them. (It’s only
approximate because—among other things—perceptual color space is
non-Euclidean.)&lt;/p&gt;

&lt;p&gt;Therefore we’ll pick colors from a circle in CIELAB space. This space
has three coordinates: L, for lightness, A for green-red, and B for
blue-yellow (hence the LAB). We determined by experimentation that a
good lightness to use was 73 out of 100. Given this lightness, we
picked the largest saturation possible, using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A^2 + B^2 = 40^2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now how do we vary the hue? Every color picked needs a new hue, and
they need to all be as different as possible. It would be bad, for
instance, if we picked 13 colors, and then the 13th color looked just
like the 2nd color.&lt;/p&gt;

&lt;p&gt;Our solution was to have each color’s hue be the
&lt;a href=&quot;https://en.wikipedia.org/wiki/Golden_angle&quot;&gt;golden angle&lt;/a&gt; from the previous
hue. From Wikipedia, the golden angle is “the angle subtended by the
smaller arc when two arcs that make up a circle are in the golden
ratio”. It is also 1/ϕ^2 of a circle, or about 137 degrees.&lt;/p&gt;

&lt;p&gt;Thus the phillogenic algorithm keeps track of the number of colors
generated so far, and assigns the n’th color a hue of n times the
golden angle. So the first color will have a hue of 0
degrees. The second color will have a hue of 137 degrees. The third will have
a hue of 137 * 2 = 274 degrees. The fourth will be 137 * 3 = 411 = 51
degrees. This is a &lt;em&gt;little&lt;/em&gt; close to the first color. But even if we
knew we’d have four colors total, they’d be at most 90 degrees
apart, so 51 isn’t too bad. This trend continues: as we pick more and
more colors, they never end up much closer to one another than is
necessary.&lt;/p&gt;

&lt;p&gt;There’s a reason that no two colors end up too similar. It follows
from the fact that ϕ is
&lt;a href=&quot;https://www.quora.com/Why-it-is-said-that-the-golden-ratio-phi-is-the-most-difficult-irrational-number-to-approximate-rationally&quot;&gt;the most difficult number to approximate as a fraction&lt;/a&gt;.
Here’s a proof that colors aren’t similar:&lt;/p&gt;

&lt;p&gt;Suppose that the m’th color and the (m+n)’th color end up being very
similar. The difference between the m’th and (m+n)’th colors is the
same as the difference between the 0’th and the n’th colors. Thus we
are supposing that the 0’th color and the n’th color are very similar.&lt;/p&gt;

&lt;p&gt;Let’s measure angles in &lt;em&gt;turns&lt;/em&gt;, or fractions of 360 degrees. The n’th
color’s hue is, by definition, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n/ϕ^2 % 1&lt;/code&gt; turns. The 0’th hue is 0.
So if these colors are similar, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n/ϕ^2 % 1 ~= 0&lt;/code&gt; (using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~=&lt;/code&gt;
for “approximately equals”). We can then reason as follows, using in
the third step the fact that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ϕ^2 - ϕ - 1 = 0&lt;/code&gt; so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ϕ^2 = ϕ + 1&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;n/ϕ^2 % 1 ~= 0
n/ϕ^2 ~= k    for some integer k
ϕ^2 ~= n/k
1 + ϕ ~= n/k
ϕ ~= (n-k)/k
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, if n is small, then k is small (because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n/k ~= ϕ^2&lt;/code&gt;), so
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(n-k)/k&lt;/code&gt; is a fraction with a small denominator. But ϕ is difficult
to approximate with fractions, and the smaller the denominator the
worse the approximation, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ϕ&lt;/code&gt; actually isn’t very close to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(n-k)/k&lt;/code&gt;, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n/ϕ^2 % 1&lt;/code&gt; actually isn’t very close to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;, so the
n’th color actually isn’t very similar to the 0’th color.&lt;/p&gt;

&lt;p&gt;And that’s why the phillotactic colors work.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Can We Crowdsource Language Design?</title>
   <link href="http://blog.brownplt.org/2017/07/06/crowd-pl-design.html"/>
   <updated>2017-07-06T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2017/07/06/crowd-pl-design</id>
   <content type="html">&lt;p&gt;Programming languages are user interfaces.
There are several ways of making decisions when designing user
interfaces, including:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;a small number of designers make all the decisions, or&lt;/li&gt;
  &lt;li&gt;user studies and feedback are used to make decisions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most programming languages have been designed by a Benevolent Dictator for Life
or a committee, which corresponds to the first model. What happens if
we try out the second?&lt;/p&gt;

&lt;p&gt;We decided to explore this question. To get a large enough number of
answers (and to engage in rapid experimentation), we decided to conduct
surveys on Amazon Mechanical Turk, a forum known to have many
technically literate people. We studied a wide range of common
programming languages features, from numbers to scope to objects to
overloading behavior.&lt;/p&gt;

&lt;p&gt;We applied two concrete measures to the survey results:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;Consistency&lt;/em&gt;: whether individuals answer similar questions the same way, and&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;Consensus&lt;/em&gt;: whether we find similar answers across individuals.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Observe that a high value of either one has clear implications for
language design, and if both are high, that suggests we have zeroed in
on a “most natural” language.&lt;/p&gt;

&lt;p&gt;As &lt;a href=&quot;https://en.wikipedia.org/wiki/Betteridge%27s_law_of_headlines&quot;&gt;Betteridge’s Law&lt;/a&gt;
suggests, we found neither. Indeed,&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;A surprising percentage of workers expected some kind of dynamic scope (83.9%).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Some workers thought that record access would distribute over the
field name expression.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Some workers ignored type annotations on functions.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Over the field and method questions we asked on objects, &lt;em&gt;no&lt;/em&gt; worker
expected Java’s semantics across all three.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These and other findings are explored in detail in
&lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/tpk-crowdsource-lang-design/&quot;&gt;our paper&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Crowdsourcing User Studies for Formal Methods</title>
   <link href="http://blog.brownplt.org/2017/07/03/fmtools-use-crowd.html"/>
   <updated>2017-07-03T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2017/07/03/fmtools-use-crowd</id>
   <content type="html">&lt;p&gt;For decades, we have neglected performing serious user studies of
formal-methods tools. This is now starting to change. An
&lt;a href=&quot;/2017/07/01/fmtools-usability.html&quot;&gt;earlier post&lt;/a&gt;
introduces our new work in this area.&lt;/p&gt;

&lt;p&gt;That study works with students in an upper-level class, who are a
fairly good proxy for some developers (and are anyway an audience we
have good access to). Unfortunately, student populations are
problematic for several reasons:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;There are only so many students in a class. There may not be enough
to obtain statistical strength, especially on designs that require
A/B testing and the like.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The class is offered only so often. It may take a whole year between
studies. (This is a common problem in computing education research.)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;As students progress through a class, it’s hard to “rewind” them and
study their responses at an earlier stage in their learning.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And so on. It would be helpful if we could obtain large numbers of
users quickly, relatively cheaply, and repeatedly.&lt;/p&gt;

&lt;p&gt;This naturally suggests crowdsourcing. Unfortunately, the tasks we are
examining involve using tools based on formal logic, not identifying
birds or picking Web site colors (or solving CAPTCHAs…). That would
seem to greatly limit the utility of crowd-workers on popular sites
like Mechanical Turk.&lt;/p&gt;

&lt;p&gt;In reality, this depends on how the problem is phrased. If we view it
as “Can we find lots of Turkers with knowledge of Promela (or Alloy or
…)?”, the answer is pretty negative. If, however, we can rework the
problems somewhat so the question is “Can we get people to work on a
puzzle?”, we can find many, many more workers. That is, sometimes the
problem is one of vocabulary (and in particular, the use of specific
formal methods languages) than of raw ability.&lt;/p&gt;

&lt;p&gt;Concretely, we have taken the following steps:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Adapt problems from being questions about Alloy specifications to
being phrased as logic “puzzles”.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Provide an initial &lt;em&gt;training&lt;/em&gt; phase to make sure workers understand
what we’re after.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Follow that with an &lt;em&gt;evaluation&lt;/em&gt; phase to ensure that they “got the
idea”. Only consider responses from those workers who score at a
high enough threshold on evaluation.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Only then conduct the actual study.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Observe that even if we don’t want to trust the final results obtained
from crowdsourcing, there are still uses for this process. Designing a
good study requires several rounds of prototyping: even simple wording
choices can have huge and unforeseen (negative) consequences. The more
rounds we get to test a study, the better it will come out. Therefore,
the crowd is useful at least to prototype and refine a study before
unleashing it on a more qualified, harder-to-find audience — a group
that, almost by definition, you do not want to waste on a first-round
study prototype.&lt;/p&gt;

&lt;p&gt;For more information, see
&lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/dnhkd-user-st-princ-mod-find-out/&quot;&gt;our paper&lt;/a&gt;.
We find fairly useful results using workers on Mechanical Turk. In
many cases the findings there correspond with those we found with
class students.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>User Studies of Principled Model Finder Output</title>
   <link href="http://blog.brownplt.org/2017/07/01/fmtools-usability.html"/>
   <updated>2017-07-01T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2017/07/01/fmtools-usability</id>
   <content type="html">&lt;p&gt;For decades, formal-methods tools have largely been evaluated on their
correctness, completeness, and mathematical foundations while
side-stepping or hand-waving questions of &lt;em&gt;usability&lt;/em&gt;.
As a result, tools like model checkers,
model finders, and proof assistants can require years of expertise to
negotiate, leaving knowledgeable but uninitiated potential users at a loss.
This state of affairs must change!&lt;/p&gt;

&lt;p&gt;One class of formal tool, model finders, provides concrete instances
of a specification, which can guide a user’s intuition or witness the
failure of desired properties. But are the examples produced actually
helpful?  Which examples ought to be shown first? How should they be
presented, and what supplementary information can aid comprehension?
Indeed, &lt;em&gt;could they even hinder understanding&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;We’ve set out to answer these questions via disciplined user-studies. 
Where can we find participants for these studies? Ideally, we would survey
experts. Unfortunately, it has been challenging to do so in the quantities
needed for statistical power. As an alternative, we have begun to use formal
methods students in Brown’s upper-level
&lt;a href=&quot;http://cs.brown.edu/courses/info/csci1950-y/&quot;&gt;Logic for Systems&lt;/a&gt;
class. The course begins with
Alloy, a popular model-finding tool, so students are well suited to
participate in basic studies. With this population, we have found some
surprising results that call into question some intuitively appealing answers
to (e.g.) the example-selection question.&lt;/p&gt;

&lt;p&gt;For more information, see
&lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/dnhkd-user-st-princ-mod-find-out/&quot;&gt;our paper&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Okay, that’s student populations. But there are only so many students
in a class, and they take the class only so often, and it’s hard to
“rewind” them to an earlier point in a course. Are there audiences we
can use that don’t have these problems? Stay tuned for our next post.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>A Third Perspective on Hygiene</title>
   <link href="http://blog.brownplt.org/2017/06/20/scope-inference-hygiene.html"/>
   <updated>2017-06-20T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2017/06/20/scope-inference-hygiene</id>
   <content type="html">&lt;p&gt;In &lt;a href=&quot;/2017/06/12/scope-inference.html&quot;&gt;the last post&lt;/a&gt;, we talked about
&lt;em&gt;scope inference&lt;/em&gt;: automatically inferring scoping rules for syntatic
sugar. In this post we’ll talk about the perhaps surprising connection
between scope inference and hygiene.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Hygiene can be viewed from a number of perspectives and defined in a
number of ways. We’ll talk about two pre-existing perspectives, and
then give a third perspective that comes from having scope inference.&lt;/p&gt;

&lt;h3 id=&quot;first-perspective&quot;&gt;First Perspective&lt;/h3&gt;

&lt;p&gt;The traditional perspective on hygiene (going all the way back to
&lt;a href=&quot;http://www.cs.indiana.edu/pub/techreports/TR194.pdf&quot;&gt;Kohlbecker in ’86&lt;/a&gt;)
defines it by what &lt;em&gt;shouldn’t&lt;/em&gt; happen when you expand macros /
syntactic sugar. To paraphrase the idea:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Expanding syntactic sugar should not cause accidental variable capture.
For instance, a variable used in a sugar should not come to refer to a
variable declared in the program simply because it has the same
name.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thus, hygiene in this tradition is defined by a &lt;em&gt;negative&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It has also traditionally focused strongly on algorithms. One would
expect papers on hygiene to state a definition of hygiene, give an
algorithm for macro expansion, and then prove that the algorithm obeys
these properties. But this last step, the proof, is usually
suspiciously missing. At least part of the reason for this, we
suspect, is that definitions of hygiene have been too informal to be
used in a proof.&lt;/p&gt;

&lt;p&gt;And a definition of hygiene has been surprisingly hard to pin down
precisely. In 2015, a full 29 years after Kohlbecker’s seminal work,
&lt;a href=&quot;http://dl.acm.org/citation.cfm?doid=2676726.2677013&quot;&gt;Adams&lt;/a&gt;
writes that “Hygiene is an essential aspect of Scheme’s macro
system that prevents unintended variable capture. However, previous
work on hygiene has focused on algorithmic implementation rather than
precise, mathematical definition of what constitutes hygiene.”
He goes on to discuss “observed-binder hygiene”, which is
“not often discussed but is implicitly averted by traditional
hygiene algorithms”. The point we’re trying to make is that the
traditional view on hygiene is &lt;em&gt;subtle&lt;/em&gt;.&lt;/p&gt;

&lt;h3 id=&quot;second-perspective&quot;&gt;Second Perspective&lt;/h3&gt;

&lt;p&gt;There is a much cleaner definition of hygiene, however, that is more
of a positive statement (and subsumes the preceding issues):&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If two programs are α-equivalent (that is, they are the same
up to renaming variables), then when you desugar them (that is, expand
their sugars) they should still be α-equivalent.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Unfortunately, this definition only makes sense if we have scope
defined on both the full and base languages. Most hygiene
systems can’t use this definition, however, because the full
language is not usually given explicit scoping rules; rather, it’s
defined implicitly through translation into the base language.&lt;/p&gt;

&lt;p&gt;Recently,
&lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.73.6117&quot;&gt;Herman and Wand&lt;/a&gt;
have advocated for &lt;em&gt;specifying&lt;/em&gt; the scoping rules for the full language
(in addition to the base language), and then &lt;em&gt;verifying&lt;/em&gt; that this
property holds. If the property doesn’t hold, then either the scope
specification or the sugar definitions are incorrect. This is,
however, an onerous demand to place on the developer of syntactic
sugar, especially since scope can be
&lt;a href=&quot;/2017/06/12/scope-inference.html#how-it-works&quot;&gt;surprisingly tricky&lt;/a&gt;
to define precisely.&lt;/p&gt;

&lt;h3 id=&quot;third-perspective&quot;&gt;Third Perspective&lt;/h3&gt;

&lt;p&gt;Scope inference gives a third perspective. Instead of requiring
authors of syntactic sugar to &lt;em&gt;specify&lt;/em&gt; the scoping rules for the full
language, we give an algorithm that &lt;em&gt;infers&lt;/em&gt; them. We have to then
define what it means for this algorithm to work “correctly”.&lt;/p&gt;

&lt;p&gt;We say that an inferred scope is correct precisely if the second
definition of hygiene holds: that is, if desugaring preserves
α-equivalence. Thus, our scope inference algorithm finds scoping
rules such that this property holds, and if no such scoping rules
exist then it fails. (And if there are &lt;em&gt;multiple&lt;/em&gt; sets of scoping rules to
choose from, it chooses the ones that put as few names in scope as
possible.)&lt;/p&gt;

&lt;p&gt;An analogy would be useful here. Think about type inference: it finds type
annotations that could be put in your program such that it would type check,
and if there are multiple options then it picks the most general one.
Scope inference similarly finds scoping rules for the full language such that
desugaring preserves α-equivalence, and if there are multiple
options then it picks the one that puts the fewest names in scope.&lt;/p&gt;

&lt;p&gt;This new perspective on hygiene allows us to shift the focus from
&lt;em&gt;expansion algorithms&lt;/em&gt; to the sugars themselves. When your focus is on
an expansion algorithm, you have to deal with whatever syntactic sugar
is thrown your way. If a sugar introduces unbound identifiers, then
the programmer (who uses the macro) just has to deal with it.
Likewise, if a sugar uses scope inconsistently, treating a variable
either as a declaration or a reference depending on the phase of the
moon, the programmer just has to deal with it. In contrast, since we
&lt;em&gt;infer&lt;/em&gt; scope for the full language, we check &lt;em&gt;check&lt;/em&gt; weather a sugar
would do one of these bad things, and if so we can call the &lt;strong&gt;sugar&lt;/strong&gt;
unhygienic.&lt;/p&gt;

&lt;p&gt;To be more concrete, consider a desugaring
rule for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bad(x, expression)&lt;/code&gt; that sometimes expands
to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lambda x: expression&lt;/code&gt; and sometimes expands to just &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;expression&lt;/code&gt;,
depending on the context. Our algorithm would infer from the first
rewrite that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;expression&lt;/code&gt; must be in scope of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt;. However, this would
mean that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;expression&lt;/code&gt; was allowed to contain references to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt;,
which would become unbound when the second rewrite was used! Our
algorithm detects this and rejects this desugaring rule. Traditional
macro systems allow this, and only detect the potential unbound
identifier problem when it actually occurred. The paper contains a
more interesting example called “lambda flip flop” that is rejected
because it uses scope inconsistently.&lt;/p&gt;

&lt;p&gt;Altogether, scope inference rules out bad sugars that cannot be made
hygienic, but if there is any way to make a sugar hygienic it will
find it.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Again, here’s the
&lt;a href=&quot;http://cs.brown.edu/research/plt/dl/icfp2017/&quot;&gt;paper and implementation&lt;/a&gt;,
if you want to read more or try it out.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Scope Inference, a.k.a. Resugaring Scope Rules</title>
   <link href="http://blog.brownplt.org/2017/06/12/scope-inference.html"/>
   <updated>2017-06-12T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2017/06/12/scope-inference</id>
   <content type="html">&lt;p&gt;&lt;em&gt;This is the second post in a series about resugaring.
It focuses on resugaring scope rules.
See also our posts on
&lt;a href=&quot;/2016/02/06/resugaring.html&quot;&gt;resugaring evaluation steps&lt;/a&gt;
and &lt;a href=&quot;/2018/06/19/resugaring-type-rules.html&quot;&gt;resugaring type rules&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Many programming languages have syntactic sugar. We would hazard to
guess that &lt;em&gt;most&lt;/em&gt; modern languages do. This is when a piece of syntax
in a language is defined in terms of the rest of the language. As a
simple example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x += expression&lt;/code&gt; might be shorthand for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x = x +
expression&lt;/code&gt;. A more interesting sugar is
&lt;a href=&quot;http://www.pyret.org&quot;&gt;Pyret&lt;/a&gt;’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; loops.
For example:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;for fold(p from 1, n from range(1, 6)):
  p * n
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;computes 5 factorial, which is 120. This &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; is a piece of sugar,
though, and the above code is secretly shorthand for:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fold(lam(p, n): p * n end, 1, range(1, 6))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Sugars like this are &lt;em&gt;great&lt;/em&gt; for language development:
they let you grow a language without making it more complicated.&lt;/p&gt;

&lt;p&gt;Languages also have &lt;em&gt;scoping rules&lt;/em&gt; that say where variables are in
scope. For instance, the scoping rules should say that a function’s
parameters are in scope in the body of the function, but not in scope
outside of the function. Many nice features in editors depend on these
scoping rules. For instance, if you use autocomplete for variable
names, it should only suggest variables that are in scope. Similarly,
refactoring tools that rename variables need to know what is in scope.&lt;/p&gt;

&lt;p&gt;This breaks down in the presence of syntactic sugar, though: how can
your editor tell what the scoping rules for a sugar are?&lt;/p&gt;

&lt;p&gt;The usual approach is to write down all of the scoping rules for all
of the sugars. But this is error prone (you need to make sure that
what you write down matches the actual behavior of the sugars), and
tedious. It also goes against a general principle we hold: to add a
sugar to a language, &lt;em&gt;you should just add the sugar to the language&lt;/em&gt;.
You shouldn’t also need to update your scoping rules, or update your
type system, or update your debugger: that should all be done
automatically.&lt;/p&gt;

&lt;p&gt;We’ve just published a paper at ICFP that shows how to &lt;em&gt;automatically&lt;/em&gt;
infer the scoping rules for a piece of sugar, like the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; example
above. Here is the
&lt;a href=&quot;http://cs.brown.edu/research/plt/dl/icfp2017/&quot;&gt;paper and implementation&lt;/a&gt;.
This is the latest work we’ve done with the goal of making the above
principle a reality. &lt;a href=&quot;/2016/02/06/resugaring.html&quot;&gt;Earlier&lt;/a&gt;, we showed
how to automatically find evaluation steps that show how your program
runs in the presence of syntatic sugar.&lt;/p&gt;

&lt;h3 id=&quot;how-it-works&quot;&gt;How it Works&lt;/h3&gt;

&lt;p&gt;Our algorithm needs two things to run:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The definitions of syntactic sugar. These are given as
pattern-based rewrite rules, saying what patterns match and what
they should be rewritten to.&lt;/li&gt;
  &lt;li&gt;The scoping rules for the base (i.e. core) language.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It then automatically infers scoping rules for the full language,
that includes the sugars. The final step to make this useful would be
to add these inferred scoping rules to editors that can use them, such
as Sublime, Atom, CodeMirror, etc.&lt;/p&gt;

&lt;p&gt;For example, we have tested it on Pyret (as well as other languages).
We gave it scoping rules for Pyret’s base language (which included
things like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lambda&lt;/code&gt;s and function application), and we gave it rules
for how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; desugars, and it determined the scoping rules of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt;. In particular:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The variables declared in each &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;from&lt;/code&gt; clause are visible in the
body, but not in the argument of any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;from&lt;/code&gt; clause.&lt;/li&gt;
  &lt;li&gt;If two &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;from&lt;/code&gt; clauses both declare the same variable, the second one
shadows the first one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This second rule is exactly the sort of thing that is easy to overlook
if you try to write these rules down by hand, resulting in obscure
bugs (e.g. when doing automatic variable refactoring).&lt;/p&gt;

&lt;!-- In the [next post](/2017/06/10/scope-inference-hygiene.md),
we&apos;ll talk about how this all related to hygiene. --&gt;

&lt;hr /&gt;

&lt;p&gt;Here are the
&lt;a href=&quot;http://cs.brown.edu/research/plt/dl/icfp2017/&quot;&gt;paper and implementation&lt;/a&gt;,
if you want to read more or try it out.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The PerMission Store</title>
   <link href="http://blog.brownplt.org/2017/02/21/permission-store.html"/>
   <updated>2017-02-21T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2017/02/21/permission-store</id>
   <content type="html">&lt;p&gt;&lt;em&gt;This is Part 2 of our series on helping users manage app permissions. 
&lt;a href=&quot;/2017/01/25/permission-app-classification.html&quot;&gt;Click here to read Part 1&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As discussed in 
&lt;a href=&quot;/2017/01/25/permission-app-classification.html&quot;&gt;Part 1&lt;/a&gt; 
of this series, one type of privacy decision users have to make is which app 
to install. Typically, when choosing an app, users pick from the first few apps 
that come up when they search a keyword in their app store, so the app store 
plays a big roll in which apps users download.&lt;/p&gt;

&lt;p&gt;Unfortunately, most major app stores don’t help users make this decision in a 
privacy-minded way. Because these stores don’t factor privacy into their 
ranking, the top few search results probably aren’t the most privacy-friendly, 
so users are already picking from a problematic pool. Furthermore, users rely 
on information in the app store to choose from within that limited pool, and 
most app stores offer very little in the way of privacy information.&lt;/p&gt;

&lt;p&gt;&lt;img width=&quot;45%&quot; src=&quot;https://blog.brownplt.org/img/permission_store_search_res.png&quot; align=&quot;left&quot; style=&quot;margin:0px 10px 10px 10px&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We’ve built a marketplace, the PerMission Store, that tackles both the ranking 
and user information concerns by adding one key component: permission-specific 
ratings. These are user ratings, much like the star ratings in the Google Play 
store, but they are specifically about an app’s permissions.&lt;sup&gt;1&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;To help users find more privacy friendly apps, the privacy ratings are 
incorporated into the PerMission Store’s ranking mechanism, so that apps with 
better privacy scores are more likely to appear in the top hits for a given 
search. (We also consider factors like the star rating in our ranking, so 
users are still getting &lt;em&gt;useful&lt;/em&gt; apps.)  So users are selecting from a more 
privacy-friendly pool of apps right off the bat.&lt;/p&gt;

&lt;p&gt;Apps’ privacy ratings are also displayed in an easy-to-understand way, 
alongside other basic information like star rating and developer. This makes 
it straightforward for users to consider privacy along with other key factors 
when deciding which app to install.&lt;/p&gt;

&lt;p&gt;Incorporating privacy into the store itself makes it so that choosing 
privacy-friendly apps is as a natural as choosing useful apps.&lt;/p&gt;

&lt;p&gt;The PerMission Store is currently available as an Android app and 
&lt;a href=&quot;https://play.google.com/store/apps/details?id=com.permission.store&quot;&gt;can be found on Google Play&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A more detailed discussion of the PerMission Store can be found in Section 3.1 of 
&lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/qsk-on-a-permission/&quot;&gt;our paper&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is Part 2 of our series on helping users manage app permissions. 
&lt;a href=&quot;/2017/01/25/permission-app-classification.html&quot;&gt;Click here to read Part 1&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;sub&gt;1: As a bootstrapping mechanism, we’ve collected rating for a couple thousand 
apps from Mechanical Turk. Ultimately, though, we expect the ratings to come 
from in-the-wild users.&lt;/sub&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Examining the Privacy Decisions Facing Users</title>
   <link href="http://blog.brownplt.org/2017/01/25/permission-app-classification.html"/>
   <updated>2017-01-25T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2017/01/25/permission-app-classification</id>
   <content type="html">&lt;p&gt;&lt;em&gt;This is Part 1 of our series on helping users manage app permissions. 
&lt;a href=&quot;/2017/02/21/permission-store.html&quot;&gt;Click here to read Part 2&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It probably comes as no surprise to you that users are taking their privacy in 
their hands every time they install or use apps on their smartphones (or tablets, 
or watches, or cars, or…). This begs the question, what kinds of privacy decisions 
are users actually making? And how can we help them with those decisions?&lt;/p&gt;

&lt;p&gt;At first blush, users can manage privacy in two ways: by choosing which apps to 
install, and by managing their apps’ permissions once they’ve installed them. For 
the first type of decision, users could benefit from a privacy-conscious app store 
to help them find more privacy-respecting apps. For the second type of decision, 
users would be better served by an assistant that helps them decide which permissions 
to grant.&lt;/p&gt;

&lt;p&gt;Users can only making installation decisions when they actually have a meaningful 
choice between different apps. If you’re looking for Facebook, there really aren’t 
any other apps that you could use instead. This left us wondering if users &lt;em&gt;ever&lt;/em&gt; 
have a meaningful choice between different apps, or whether they are generally 
looking for a &lt;em&gt;specific&lt;/em&gt; app.&lt;/p&gt;

&lt;p&gt;To explore this question, we surveyed Mechanical turk workers about 66 different 
Android apps, asking whether they thought the app could be replaced by a different 
one. The apps covered a broad range of functionality, from weather apps, to games, 
to financial services.&lt;/p&gt;

&lt;p&gt;It turns out that apps vary greatly in their “replaceability,” and, rather than 
falling cleanly into “replaceable” and “unique” groups, they run along a spectrum 
between the two. At one end of the spectrum you have apps like Instagram, which less 
than 20% of workers felt could be replaced. On the other end of the spectrum are apps 
like Waze, which 100% of workers felt was replaceable. In the middle are apps whose 
replaceability depends on which features you’re interested in. For example, take an 
app like Strava, which lets you track your physical activity and compete with friends. 
If you only want to track yourself, it could be replaced by something like MapMyRide, 
but if you’re competing with friends who all use Strava, you’re pretty much stuck with 
Strava.&lt;/p&gt;

&lt;p&gt;Regardless of exactly which apps fall where on the spectrum, though, there &lt;em&gt;are&lt;/em&gt; 
replaceable apps, so users are making real decisions about which apps to install. And, 
for irreplaceable apps, they are also having to decide how to manage those apps’ 
permissions. These two types of decisions require two approaches to assisting users. 
A privacy-aware marketplace would aid users with installation decisions by helping them 
find more privacy-respecting apps, while a privacy assistant could help users manage 
their apps’ permissions.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/2017/02/21/permission-store.html&quot;&gt;Click here&lt;/a&gt; 
to read about our privacy-aware marketplace, the PerMission Store, and stay tuned for 
our upcoming post on a privacy assistant!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A more detailed discussion of this study can be found in Section 2 of 
&lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/qsk-on-a-permission/&quot;&gt;our paper&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>The Pyret Programming Language: Why Pyret?</title>
   <link href="http://blog.brownplt.org/2016/06/26/why-pyret.html"/>
   <updated>2016-06-26T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2016/06/26/why-pyret</id>
   <content type="html">&lt;p&gt;We need better languages for introductory computing. A good
introductory language makes good compromises between expressiveness
and performance, and between simplicity and feature-richness. Pyret is
our evolving experiment in this space.&lt;/p&gt;

&lt;p&gt;Since we expect our answer to this question will evolve over time, we’ve picked
a place for our case for the language to live, and will update it over time:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.pyret.org/pyret-code/&quot;&gt;The Pyret Code; or A Rationale for The Pyret Programming Language&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first version answers a few questions that we expect many people have when
considering languages in general and languages for education in particular:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Why not just use Java, Python, Racket, OCaml, or Haskell?&lt;/li&gt;
  &lt;li&gt;Will Pyret ever be a full-fledged programming language?&lt;/li&gt;
  &lt;li&gt;But there are lots of kinds of “education”!&lt;/li&gt;
  &lt;li&gt;What are some ways the educational philosophy influences the langauge?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post, it’s worth answering one more immediate question:&lt;/p&gt;

&lt;h3 id=&quot;whats-going-on-right-now-and-whats-next&quot;&gt;What’s going on right now, and what’s next?&lt;/h3&gt;

&lt;p&gt;We are currently hard at work on three very important features:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Support for static typing. Pyret will have a conventional type
system with tagged unions and a type &lt;em&gt;checker&lt;/em&gt;, resulting in
straightforward type errors without the complications associated
with type &lt;em&gt;inference&lt;/em&gt; algorithms. We have carefully designed Pyret
to always be typeable, but our earlier type systems were not good
enough. We’re pretty happy with how this one is going.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Tables are a critical type for storing real-world data. Pyret is
adding linguistic and library support for working effectively with
tables, which PAPL will use to expose students to “database”
thinking from early on.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Our model for interactive computation is based on the
&lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/fffk-functional-io/&quot;&gt;“world” model&lt;/a&gt;. 
We are currently revising and updating it in a few ways that will
help it better serve our new educational programs.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the educational side, Pyret is already used by the
&lt;a href=&quot;http://www.bootstrapworld.org/&quot;&gt;Bootstrap project&lt;/a&gt;. We are now
developing three new curricula for Bootstrap:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;A CS1 curriculum, corresponding to a standard introduction to
computer science, but with several twists based on our pedagogy and
materials.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A CS Principles curriculum, for the new US College Board Advanced
Placement exam.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A physics/modeling curriculum, to help teach students physics and
modeling through the medium of programming.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’d like to stay abreast of our developments or get involved in
our discussions, please
&lt;a href=&quot;http://www.pyret.org/discuss/&quot;&gt;come on board&lt;/a&gt;!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Resugaring Evaluation Sequences</title>
   <link href="http://blog.brownplt.org/2016/02/06/resugaring.html"/>
   <updated>2016-02-06T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2016/02/06/resugaring</id>
   <content type="html">&lt;p&gt;&lt;em&gt;This is the first post in a series about resugaring.
It focuses on resugaring evaluation sequences.
See also our later posts on
&lt;a href=&quot;/2017/06/12/scope-inference.html&quot;&gt;resugaring scope rules&lt;/a&gt;
and &lt;a href=&quot;/2018/06/19/resugaring-type-rules.html&quot;&gt;resugaring type rules&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;A lot of programming languages are defined in terms of syntactic
sugar. This has many advantages, but also a couple of drawbacks. In this
post, I’m going to tell you about one of these drawbacks, and the solution
we found for it. First, though, let me describe what syntactic sugar
is and why it’s used.&lt;/p&gt;

&lt;p&gt;Syntactic sugar is when you define a piece of syntax in a language in
terms of the rest of the language. You’re probably already familiar
with many examples. For instance, in Python, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x + y&lt;/code&gt; is syntactic
sugar for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x.__add__(y)&lt;/code&gt;. I’m going to use the word “desugaring”
to mean the expansion of syntactic sugar, so I’ll say that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x + y&lt;/code&gt;
&lt;em&gt;desugars&lt;/em&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x.__add__(y)&lt;/code&gt;. Along the same lines, in
Haskell, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[f x | x &amp;lt;- lst]&lt;/code&gt; desugars to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map f lst&lt;/code&gt;. (Well, I’m
simplifying a little bit; the full desugaring is given by the
&lt;a href=&quot;http://www.haskell.org/onlinereport/exps.html#list-comprehensions&quot;&gt;Haskell 98 spec&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;As a programming language researcher I love syntactic sugar, and you
should too. It splits a language into two parts: a big “surface” language
that has the sugar, and a much smaller “core” language that lacks it. This
separation lets programmers use the surface language
that has all of the features they know and love, while letting tools work
over the much simpler core language, which lets the tools themselves be
simpler and more robust.&lt;/p&gt;

&lt;p&gt;There’s a problem, though (every blog post needs a problem). What
happens when a tool, which has been
working over the core language, tries to show code to the programmer,
who has been working over the surface? Let’s zoom in on one instance
of this problem. Say you write a little snippet of code, like so:
(This code is written in &lt;em&gt;an old version of&lt;/em&gt; &lt;a href=&quot;http://www.pyret.org&quot;&gt;Pyret&lt;/a&gt;;
it should be readable even if you don’t know the language.)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;my-list = [2]
cases(List) my-list:
  | empty() =&amp;gt; print(&quot;empty&quot;)
  | link(something, _) =&amp;gt;
    print(&quot;not empty&quot;)
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And now say you’d like to see how this code runs. That is, you’d like
to see an &lt;em&gt;evaluation sequence&lt;/em&gt; (a.k.a. an execution trace) of this
program. Or maybe you already know what it will do, but you’re
teaching students, and would like to show them how it will run. Well,
what &lt;em&gt;actually&lt;/em&gt; happens when you run this code is that it is first
desugared into the core, like so:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;my-list = list.[&quot;link&quot;](2, list.[&quot;empty&quot;])
block:
  tempMODRIOUJ :: List = my-list
  tempMODRIOUJ.[&quot;_match&quot;]({
    &quot;empty&quot; : fun(): print(&quot;empty&quot;) end,
    &quot;link&quot; : fun(something, _):
      print(&quot;not empty&quot;) end
},
fun(): raise(&quot;cases: no cases matched&quot;) end)
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This core code is then run (each block of code is the next evaluation step):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;my-list = obj.[&quot;link&quot;](2, list.[&quot;empty&quot;])
block:
tempMODRIOUJ :: List = my-list
  tempMODRIOUJ.[&quot;_match&quot;]({&quot;empty&quot; : fun():   print(&quot;empty&quot;) end,
  &quot;link&quot; : fun(something, _):   print(&quot;not empty&quot;) end}, fun():
  raise(&quot;cases: no cases matched&quot;) end)
  end

my-list = obj.[&quot;link&quot;](2, list.[&quot;empty&quot;])
block:
tempMODRIOUJ :: List = my-list
  tempMODRIOUJ.[&quot;_match&quot;]({&quot;empty&quot; : fun():   print(&quot;empty&quot;) end,
  &quot;link&quot; : fun(something, _):   print(&quot;not empty&quot;) end}, fun():
  raise(&quot;cases: no cases matched&quot;) end)
  end

my-list = &amp;lt;func&amp;gt;(2, list.[&quot;empty&quot;])
block:
tempMODRIOUJ :: List = my-list
  tempMODRIOUJ.[&quot;_match&quot;]({&quot;empty&quot; : fun():   print(&quot;empty&quot;) end,
  &quot;link&quot; : fun(something, _):   print(&quot;not empty&quot;) end}, fun():
  raise(&quot;cases: no cases matched&quot;) end)
  end

my-list = &amp;lt;func&amp;gt;(2, obj.[&quot;empty&quot;])
block:
tempMODRIOUJ :: List = my-list
  tempMODRIOUJ.[&quot;_match&quot;]({&quot;empty&quot; : fun():   print(&quot;empty&quot;) end,
  &quot;link&quot; : fun(something, _):   print(&quot;not empty&quot;) end}, fun():
  raise(&quot;cases: no cases matched&quot;) end)
  end

my-list = &amp;lt;func&amp;gt;(2, obj.[&quot;empty&quot;])
block:
tempMODRIOUJ :: List = my-list
  tempMODRIOUJ.[&quot;_match&quot;]({&quot;empty&quot; : fun():   print(&quot;empty&quot;) end,
  &quot;link&quot; : fun(something, _):   print(&quot;not empty&quot;) end}, fun():
  raise(&quot;cases: no cases matched&quot;) end)
  end

my-list = &amp;lt;func&amp;gt;(2, [])
block:
tempMODRIOUJ :: List = my-list
  tempMODRIOUJ.[&quot;_match&quot;]({&quot;empty&quot; : fun():   print(&quot;empty&quot;) end,
  &quot;link&quot; : fun(something, _):   print(&quot;not empty&quot;) end}, fun():
  raise(&quot;cases: no cases matched&quot;) end)
  end

my-list = [2]
block:
tempMODRIOUJ :: List = my-list
  tempMODRIOUJ.[&quot;_match&quot;]({&quot;empty&quot; : fun():   print(&quot;empty&quot;) end,
  &quot;link&quot; : fun(something, _):   print(&quot;not empty&quot;) end}, fun():
  raise(&quot;cases: no cases matched&quot;) end)
  end

tempMODRIOUJ :: List = [2]
tempMODRIOUJ.[&quot;_match&quot;]({&quot;empty&quot; : fun(): print(&quot;empty&quot;) end, &quot;link&quot; :
fun(something, _): print(&quot;not empty&quot;) end}, fun(): raise(&quot;cases: no
cases matched&quot;) end)

[2].[&quot;_match&quot;]({&quot;empty&quot; : fun(): print(&quot;empty&quot;) end, &quot;link&quot; :
fun(something, _): print(&quot;not empty&quot;) end}, fun(): raise(&quot;cases: no
cases matched&quot;) end)

[2].[&quot;_match&quot;]({&quot;empty&quot; : fun(): print(&quot;empty&quot;) end, &quot;link&quot; :
fun(something, _): print(&quot;not empty&quot;) end}, fun(): raise(&quot;cases: no
cases matched&quot;) end)

&amp;lt;func&amp;gt;({&quot;empty&quot; : fun(): end, &quot;link&quot; : fun(something, _): print(&quot;not
empty&quot;) end}, fun(): raise(&quot;cases: no cases matched&quot;) end)

&amp;lt;func&amp;gt;({&quot;empty&quot; : fun(): end, &quot;link&quot; : fun(): end}, fun():
raise(&quot;cases: no cases matched&quot;) end)

&amp;lt;func&amp;gt;(obj, fun(): raise(&quot;cases: no cases matched&quot;) end)

&amp;lt;func&amp;gt;(obj, fun(): end)

&amp;lt;func&amp;gt;(&quot;not empty&quot;)

&quot;not empty&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But that wasn’t terribly helpful, was it? &lt;em&gt;Sometimes&lt;/em&gt; you want to
see exactly what a program is doing in all its gory detail
(along the same lines, it’s occasionally helpful to see the assembly
code a program is compiling to), but most of the time it would be
nicer if you could see things in terms of the syntax you wrote the
program with! In this particular example, it would be much nicer to
see:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;my-list = [2]
cases(List) my-list:
  | empty() =&amp;gt; print(&quot;empty&quot;)
  | link(something, _) =&amp;gt;
    print(&quot;not empty&quot;)
end

my-list = [2]
cases(List) my-list:
  | empty() =&amp;gt; print(&quot;empty&quot;)
  | link(something, _) =&amp;gt;
    print(&quot;not empty&quot;)
end

cases(List) [2]:
| empty() =&amp;gt; print(&quot;empty&quot;)
| link(something, _) =&amp;gt;
  print(&quot;not empty&quot;)
end

&amp;lt;func&amp;gt;(&quot;not empty&quot;)

&quot;not empty&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(You might have noticed that the first step got repeated for what
looks like no reason. What happened there is that the &lt;em&gt;code&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[2]&lt;/code&gt;
was evaluated to an actual &lt;em&gt;list&lt;/em&gt;, which also prints itself as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[2]&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;So we built a tool that does precisely this. It turns core
evaluation sequences into surface evaluation sequences. We call the
process &lt;em&gt;resugaring&lt;/em&gt;, because it’s the opposite of desugaring:
we’re adding the syntactic sugar back into your program. The above
example is actual output from the tool, for an old version of
Pyret. I’m currently working on a version for modern Pyret.&lt;/p&gt;

&lt;h3 id=&quot;resugaring-explained&quot;&gt;Resugaring Explained&lt;/h3&gt;

&lt;p&gt;I always find it helpful to introduce a diagram when explaining
resugaring. On the right is the &lt;em&gt;core evaluation sequence&lt;/em&gt;, which is
the sequence of steps that the program takes when it actually runs.
And on the left is the &lt;em&gt;surface evaluation sequence&lt;/em&gt;, which is what
you get when you try to &lt;em&gt;resugar&lt;/em&gt; each step in the core evaluation
sequence. As a special case, the first step on the left is the
original program.&lt;/p&gt;

&lt;p&gt;Here’s an example. The starting program will be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;not(true) or true&lt;/code&gt;, where
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;not&lt;/code&gt; is in the core language, but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;or&lt;/code&gt; is defined as a piece of
sugar:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;x or y    ==desugar==&amp;gt;  let t = x in
                          if t then t else y
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And here’s the diagram:&lt;/p&gt;

&lt;p&gt;&lt;img width=&quot;100%&quot; src=&quot;https://blog.brownplt.org/img/resugar-diagram.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The steps (downarrows) in the core evaluation sequence are ground
truth: they are what happens when you actually run the program. In
contrast, the steps in the surface evaluation sequence
are made up; the whole surface evaluation sequence is an attempt at
&lt;em&gt;reconstructing&lt;/em&gt; a nice evaluation sequence by resugaring each of the
core steps.  Notice that the third core term fails to resugar. This is
because there’s no good way to represent it in terms of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;or&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;formal-properties-of-resugaring&quot;&gt;Formal Properties of Resugaring&lt;/h3&gt;

&lt;p&gt;It’s no good to build a tool without having a precise idea of what
it’s supposed to do. To this end, we came up with three properties
that (we think) capture exactly what it means for a resugared
evaluation sequence to be &lt;em&gt;correct&lt;/em&gt;. It will help to look at the
diagram above when thinking about these properties.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Emulation&lt;/strong&gt; says that every term on the left should &lt;em&gt;desugar&lt;/em&gt; to
the term to its right. This expresses the idea that the resugared
terms can’t &lt;em&gt;lie&lt;/em&gt; about the term they’re supposed to represent.
Another way to think about this is that desugaring and resugaring
are inverses.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Abstraction&lt;/strong&gt; says that the surface evaluation sequence on the
left should show a sugar precisely when the programmer used it. So,
for example, it should show things using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;or&lt;/code&gt; and not &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;let&lt;/code&gt;,
because the original program used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;or&lt;/code&gt; but not &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;let&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Coverage&lt;/strong&gt; says that you should show as many steps as possible.
Otherwise, technically the surface evaluation sequence could just
be empty! That would satisfy both Emulation and Abstraction, which
only say things about the steps that &lt;em&gt;are&lt;/em&gt; shown.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We’ve proved that our resugaring algorithm obeys Emulation and
Abstraction, and given some good emperical evidence that it obeys
Coverage too.&lt;/p&gt;

&lt;p&gt;I’ve only just introduced resugaring. If you’d like to read more, see
&lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/pk-resuarging/&quot;&gt;the paper&lt;/a&gt;, and &lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/pk-hyg-resugaring-comp-desugaring/&quot;&gt;the followup&lt;/a&gt; that deals with hygiene
(e.g., preventing variable capture).&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Slimming Languages by Reducing Sugar</title>
   <link href="http://blog.brownplt.org/2016/01/08/slimming-languages.html"/>
   <updated>2016-01-08T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2016/01/08/slimming-languages</id>
   <content type="html">&lt;p&gt;JavaScript is a crazy language. It’s defined by 250 pages of English
prose, and even the parts of the language that &lt;em&gt;ought&lt;/em&gt; to be simple,
like addition and variable scope, are very complicated. We showed
before how to tackle this problem using
&lt;a href=&quot;/2011/09/29/js-essence.html&quot;&gt;λ&lt;sub&gt;s5&lt;/sub&gt;&lt;/a&gt;,
which is an example of what’s called a &lt;em&gt;tested semantics&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You can read about λ&lt;sub&gt;s5&lt;/sub&gt; at the above link. But the
basic idea is that λ&lt;sub&gt;s5&lt;/sub&gt; has two parts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A small &lt;em&gt;core&lt;/em&gt; language that captures the essential parts of
JavaScript, without all of its foibles, and&lt;/li&gt;
  &lt;li&gt;A &lt;em&gt;desugaring&lt;/em&gt; function that translates the full language down to
this small core.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(We typically call this core language λ&lt;sub&gt;s5&lt;/sub&gt;, even
though technically speaking it’s only part of what makes up
λ&lt;sub&gt;s5&lt;/sub&gt;.)&lt;/p&gt;

&lt;p&gt;These two components together give us an implementation of JavaScript:
to run a program, you desugar it to λ&lt;sub&gt;s5&lt;/sub&gt;, and then
run &lt;em&gt;that&lt;/em&gt; program. And with this implementation, we can run
JavaScript’s conformance test suite to check that
λ&lt;sub&gt;s5&lt;/sub&gt; is accurate: this is why it’s called a &lt;em&gt;tested&lt;/em&gt;
semantics. And lo, λ&lt;sub&gt;s5&lt;/sub&gt; passes the relevant portion
of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test262&lt;/code&gt; conformance suite.&lt;/p&gt;

&lt;h3 id=&quot;the-problem&quot;&gt;The Problem&lt;/h3&gt;

&lt;p&gt;Every blog post needs a problem, though. The problem with
λ&lt;sub&gt;s5&lt;/sub&gt; lies in desugaring. We just stated that
JavaScript is &lt;em&gt;complicated&lt;/em&gt;, while the core language for
λ&lt;sub&gt;s5&lt;/sub&gt; is &lt;em&gt;simple&lt;/em&gt;. This means that the complications
of JavaScript must be dealt with not in the &lt;em&gt;core language&lt;/em&gt;, but
instead in &lt;em&gt;desugaring&lt;/em&gt;. Take an illustrative example. Here’s a couple
of innocent lines of JavaScript:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;function id(x) {
    return x;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;These couple lines desugar into the following λ&lt;sub&gt;s5&lt;/sub&gt;
code:&lt;/p&gt;

&lt;pre&gt;
{let
 (%context = %strictContext)
 { %defineGlobalVar(%context, &quot;id&quot;);
  {let
   (#strict = true)
   {&quot;use strict&quot;;
    {let
     (%fobj4 =
       {let
         (%prototype2 = {[#proto: %ObjectProto,
                          #class: &quot;Object&quot;,
                          #extensible: true,]
                         &apos;constructor&apos; : {#value (undefined) ,
                                          #writable true ,
                                          #configurable false}})
         {let
          (%parent = %context)
          {let
           (%thisfunc3 =
             {[#proto: %FunctionProto,
               #code: func(%this , %args)
                     { %args[delete &quot;%new&quot;];
                       label %ret :
                       { {let
                          (%this = %resolveThis(#strict,
                                                %this))
                          {let
                           (%context =
                             {let
                               (%x1 = %args
                                        [&quot;0&quot; , null])
                               {[#proto: %parent,
                                 #class: &quot;Object&quot;,
                                 #extensible: true,]
                                &apos;arguments&apos; : {#value (%args) ,
                                         #writable true ,
                                         #configurable false},
                                &apos;x&apos; : {#getter func
                                         (this , args)
                                         {label %ret :
                                         {break %ret %x1}} ,
                                       #setter func
                                         (this , args)
                                         {label %ret :
                                         {break %ret %x1 := args
                                         [&quot;0&quot; , {[#proto: %ArrayProto,
                                         #class: &quot;Array&quot;,
                                         #extensible: true,]}]}}}}})
                           {break %ret %context[&quot;x&quot; , {[#proto: null,
                                                  #class: &quot;Object&quot;,
                                                  #extensible: true,]}];
                            undefined}}}}},
               #class: &quot;Function&quot;,
               #extensible: true,]
              &apos;prototype&apos; : {#value (%prototype2) ,
                             #writable true ,
                             #configurable true},
              &apos;length&apos; : {#value (1.) ,
                          #writable true ,
                          #configurable true},
              &apos;caller&apos; : {#getter %ThrowTypeError ,
                          #setter %ThrowTypeError},
              &apos;arguments&apos; : {#getter %ThrowTypeError ,
                             #setter %ThrowTypeError}})
           { %prototype2[&quot;constructor&quot; = %thisfunc3 , null];
             %thisfunc3}}}})
     %context[&quot;id&quot; = %fobj4 ,
              {[#proto: null, #class: &quot;Object&quot;, #extensible: true,]
               &apos;0&apos; : {#value (%fobj4) ,
                      #writable true ,
                      #configurable true}}]}}}}}
&lt;/pre&gt;

&lt;p&gt;This is a bit much. It’s hard to read, and it’s hard for tools to
process. But more to the point, λ&lt;sub&gt;s5&lt;/sub&gt; is meant to be
used by researchers, and this code bloat has stood in the way of
researchers trying to adopt it. You can imagine that if you’re trying
to write a tool that works over λ&lt;sub&gt;s5&lt;/sub&gt; code, and
there’s a bug in your tool and you need to debug it, and you have to
wade through &lt;em&gt;that&lt;/em&gt; much code just for the simplest of examples, it’s
a bit of a nightmare.&lt;/p&gt;

&lt;h3 id=&quot;the-ordinary-solution&quot;&gt;The Ordinary Solution&lt;/h3&gt;

&lt;p&gt;So, there’s too much code. Fortunately there are well-known solutions
to this problem. We implemented a number of standard compiler
optimization techniques to shrink the generated λ&lt;sub&gt;s5&lt;/sub&gt;
code, while preserving its semantics. Here’s a boring list of the
&lt;em&gt;Semantics-Preserving&lt;/em&gt; optimizations we used:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Dead-code elimination&lt;/li&gt;
  &lt;li&gt;Constant folding&lt;/li&gt;
  &lt;li&gt;Constant propogation&lt;/li&gt;
  &lt;li&gt;Alias propogation&lt;/li&gt;
  &lt;li&gt;Assignment conversion&lt;/li&gt;
  &lt;li&gt;Function inlining&lt;/li&gt;
  &lt;li&gt;Infer type &amp;amp; eliminate static checks&lt;/li&gt;
  &lt;li&gt;Clean up unused environment bindings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of these are standard textbook optimizations; though the last two
are specific to λ&lt;sub&gt;s5&lt;/sub&gt;. Anyhow, we did all this and
got… &lt;strong&gt;5-10%&lt;/strong&gt; code shrinkage.&lt;/p&gt;

&lt;h3 id=&quot;the-extraordinary-solution&quot;&gt;The Extraordinary Solution&lt;/h3&gt;

&lt;p&gt;That’s it: &lt;strong&gt;5-10%&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Given the magnitude of the code bloat problem, that isn’t nearly
enough shrinkage to be helpful. So let’s take a step back and ask
where all this bloat came from. We would argue that code bloat can be
partitioned into three categories:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Intended code bloat&lt;/strong&gt;. Some of it is intentional.
λ&lt;sub&gt;s5&lt;/sub&gt; is a small core language, and there should be
some expansion as you translate to it.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Incidental code bloat&lt;/strong&gt;. The desugaring function from JS to
λ&lt;sub&gt;s5&lt;/sub&gt; is a simple recursive-descent function. It’s
purposefully not clever, and as a result it sometimes generates
redundant code. And this is exactly what the semantics-preserving
rewrites we just mentioned get rid of.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Essential code bloat&lt;/strong&gt;. Finally, some code bloat is due to the
semantics of JS.  JS is a complicated langauge with complicated
features, and they turn into complicated λ&lt;sub&gt;s5&lt;/sub&gt; code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There wasn’t much to gain by way of reducing Intended or Incidental
code bloat. But how do you go about reducing Essential code bloat?
Well, Essential bloat is the code bloat that comes from the
complications of JS. To remove it, you would simplify the language.
And we did exactly that! We defined five &lt;em&gt;Semantics-Altering&lt;/em&gt;
transformations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;(IR) Identifier restoration&lt;/strong&gt;: pretend that JS is lexically scoped&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;(FR) Function restoration&lt;/strong&gt;: pretend that JS functions are just functions
and not function-object-things.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;(FA) Fixed arity&lt;/strong&gt;: pretend that JS functions always take as many arguments
as they’re declared with.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;(UAE) Assertion elimination&lt;/strong&gt;: unsafely remove some runtime checks (your
code is correct anyways, right?)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;(SAO) Simplifying arithmetic operators&lt;/strong&gt;: eliminate strange behavior for
basic operators like “+”.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These semantics-altering transformations blasphemously &lt;em&gt;break the
language&lt;/em&gt;. This is actually OK, though! The thing is, if you’re
studying JS or doing static analysis, you probably &lt;em&gt;already&lt;/em&gt; aren’t
handling the whole language. It’s too complicated, so instead you
handle a sub-language. And this is exactly what these
semantics-altering transformations capture: they are simplifying
assumptions about the JS language.&lt;/p&gt;

&lt;h3 id=&quot;lessons-about-javascript&quot;&gt;Lessons about JavaScript&lt;/h3&gt;

&lt;p&gt;And we can learn about JavaScript from them. We implemented these
transformations for λ&lt;sub&gt;s5&lt;/sub&gt;, and so we could run the
test suite with the transformations turned on and see how many tests
broke.  This gives a crude measure of “correctness”: a transformation
is 50% correct if it breaks half the tests. Here’s the graph:&lt;/p&gt;

&lt;p&gt;&lt;img with=&quot;100%&quot; src=&quot;https://blog.brownplt.org/img/correctness_vs_shrinkage.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Notice that the semantics-altering transformations shrink code by more
than 50%: this is way better than the 5-10% that the
semantics-preserving ones gave. Going back to the three kinds of code
bloat, this shows that most code bloat in λ&lt;sub&gt;s5&lt;/sub&gt; is
Essential: it comes from the complicated semantics of JS, and if you
simplify the semantics you can make it go away.&lt;/p&gt;

&lt;p&gt;Next, here’s the shrinkages of each of the semantics-altering
transformations:&lt;/p&gt;

&lt;p&gt;&lt;img width=&quot;100%&quot; src=&quot;https://blog.brownplt.org/img/shrinkage-altering.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Since these semantics-altering transformations are simplifications of
JS semantics, and desugared code size is a measure of complexity, you
can view this graph as a (crude!) measure of complexity of language
features. In this light, notice IR (Identifier Restoration): it
crushes the other transformations by giving 30% code reduction. This
shows that JavaScript’s scope is complex: by this metric &lt;em&gt;30%&lt;/em&gt; of
JavaScript’s complexity is due to its scope.&lt;/p&gt;

&lt;h3 id=&quot;takeaway&quot;&gt;Takeaway&lt;/h3&gt;

&lt;p&gt;These semantics-altering transformations give semantic restrictions on
JS. Our paper makes these restrictions precise. And they’re exactly
the sorts of simplifying assumptions that papers need to make to
reason about JS. You can even download λ&lt;sub&gt;s5&lt;/sub&gt; from git
and implement your analysis over λ&lt;sub&gt;s5&lt;/sub&gt; with a subset
of these restrictions turned on, and &lt;em&gt;test&lt;/em&gt; it. So let’s work toward a
future where papers that talk about JS say exactly what sub-language
of JS they mean.&lt;/p&gt;

&lt;h3 id=&quot;the-paper&quot;&gt;The Paper&lt;/h3&gt;

&lt;p&gt;This is just a teaser: to read more, see &lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/lppk-slim-lang-sem-alt-trans/&quot;&gt;the paper&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>In-flow Peer Review: An Overview</title>
   <link href="http://blog.brownplt.org/2016/01/02/ifpr-idea.html"/>
   <updated>2016-01-02T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2016/01/02/ifpr-idea</id>
   <content type="html">&lt;p&gt;We ought to give students opportunities to practice code review.  It’s a
fundamental part of modern software development, and communicating clearly and
precisely about code is a skill that only develops with time.  It also helps
shape software projects for the better early on, as discussions about design
and direction in the beginning can avoid costly mistakes that need to be
undone later.&lt;/p&gt;

&lt;p&gt;Introducing code review into a curriculum faces a few challenges.  First,
there is the question of the pedagogy of code review: what code artifacts are
students qualified to review?  Reviewing entire solutions may be daunting if
students are already struggling to complete their own, and it can be
difficult to scope feedback for an entire program.  Adding review also
introduces a time cost for assignments, if it actually makes up a logically
separate assignment from the code under review.&lt;/p&gt;

&lt;p&gt;We propose &lt;em&gt;in-flow peer review&lt;/em&gt; (IFPR) as a strategy for blending some of
these constraints and goals.  The fundamental idea is to break assignments
into separately-submittable chunks, where each intermediate submittable is
designed to be amenable to a brief peer review.  The goal is for students to
practice review, benefit from the feedback they get from their peers while the
assignment is still ongoing, and also learn from seeing other approaches to
the same problem.  We’ve experimented with in-flow peer review in several
settings, and future posts will discuss more of our detailed results.  Here,
we lay out some of the design space of in-flow peer review, including which
intermediate steps might show promise, and what other choices a practitioner
of IFPR can make.  This discussion is based on our experience and on an 
&lt;a href=&quot;https://cs.brown.edu/~sk/Publications/Papers/Published/ccfhkptw-in-flow-peer-review/&quot;&gt;ITiCSE working group
report&lt;/a&gt;
that explored many of the design dimensions of IFPR.  That report has deeper
discussions of the topics we introduce here, along with many other design
dimensions and examples for IFPR.&lt;/p&gt;

&lt;h3 id=&quot;what-to-submit&quot;&gt;What to Submit&lt;/h3&gt;

&lt;p&gt;The first question we need to address is what pieces of assignments are
usefully separable and reviewable.  There are a number of factors at work
here.  For example, it may be detrimental from an evaluation point of view to
share too much of a solution while the assignment is ongoing, so the
intermediate steps shouldn’t “give away” the whole solution.  The intermediate
steps need to be small enough to review in a brief time window, but
interesting enough to prompt useful feedback.  Some examples of intermediate
steps are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Full test suites for the problem, without the associated solution&lt;/li&gt;
  &lt;li&gt;A class or structure definition used to represent a data structure, without
the associated operations&lt;/li&gt;
  &lt;li&gt;Function headers for helper functions without the associated body&lt;/li&gt;
  &lt;li&gt;Full helper functions, without the associated “main” implementation&lt;/li&gt;
  &lt;li&gt;A task-level breakdown of a work plan for a project (e.g. interface
boundaries, test plan, and class layout)&lt;/li&gt;
  &lt;li&gt;A description of &lt;em&gt;properties&lt;/em&gt; (expressed as predicates in a programming
language, or informally) that ought to be true of an eventual implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these reviewable artifacts can give students hints about a piece of
the problem without giving away full solutions, and seem capable of prompting
meaningful feedback that will inform later stages of the assignment.&lt;/p&gt;

&lt;h3 id=&quot;how-to-review&quot;&gt;How to Review&lt;/h3&gt;

&lt;p&gt;The second question has to do with the mechanics of review itself.  How many
submissions should students review (and how many reviews should they receive)?
Should students’ names be attached to their submissions and/or their reviews,
or should the process be completely anonymous?  What prompts should be given
in the review rubric to guide students towards giving useful feedback?  How
much time should students have to complete reviews, and when should they be
scheduled in the assignment process?&lt;/p&gt;

&lt;p&gt;These questions, obviously, don’t have right or wrong answers, but some in
particular are useful to discuss, especially with respect to different goals
for different classrooms.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Anonymity&lt;/strong&gt; is an interesting choice.  Professional code review is seldom
anonymous, and having students take ownership of their work encourages an
attitude of professionalism.  If reviewer-reviewee pairs can identify one
another, they can communicate outside the peer review system, as well, which
may be encouraged or not desired depending on the course.  Anonymity has a
number of benefits, in that it avoids any unconscious bias in reviews based
on knowing another student’s identity, and may make students feel more
comfortable with the process.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Rubric&lt;/strong&gt; design can heavily shape the kinds of reviews students write.  At
one extreme, students could simply get an empty text box and provide only
free-form comments.  Students could also be asked to identify specific
features in their review (“does the test suite cover the case of a list
with duplicate elements?”), fill in line-by-line comments about each part
of the submission, write test cases to demonstrate bugs that they find, or
many other structured types of feedback.  This is a pretty wide-open design
space, and the complexity and structure of the rubric can depend on
curricular goals, and on the expected time students should take for peer
review.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Scheduling&lt;/strong&gt; reviews and intermediate submissions is an interesting
balancing act.  For a week-long assignment, it may be useful to have initial
artifacts submitted as early as the second day, with reviews submitted on
the third day, in order to give students time to integrate the feedback into
their submissions.  For longer assignments, the schedule can be stretched or
involve more steps.  This can have ancillary benefits, in that students are
forced to start their assignment early in order to participate in the review
process (which can be mandatory), combatting procrastination.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;logistics-and-software-support&quot;&gt;Logistics (and Software Support)&lt;/h3&gt;

&lt;p&gt;Setting up an IFPR workflow manually would involve serious instructor effort,
so software support is a must for an easy integration of IFPR into the
classroom.  The software ought to support different review workflows and
rubrics, across various assignment durations in types, in order to be useful
in more than one class or setting.  In the next post, we’ll talk about some
design goals for IFPR software and how we’ve addressed them.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Tierless Programming for SDNs: Differential Analysis</title>
   <link href="http://blog.brownplt.org/2015/06/02/flowlog5.html"/>
   <updated>2015-06-02T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2015/06/02/flowlog5</id>
   <content type="html">&lt;style&gt;
@media only screen and (device-width: 768px) and (orientation: landscape) {
  .mobile-comment {
    display: block;
  }
}

@media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
  .mobile-comment {
    display: block;
  }
}

.mobile-comment {
  display: none;
}
&lt;/style&gt;

&lt;p&gt;
This post is part of our series about tierless network programming with Flowlog:&lt;br&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2014/09/30/flowlog1.html&quot;&gt;Part 1: Tierless Programming&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/03/01/flowlog2.html&quot;&gt;Part 2: Interfacing with External Events&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/04/13/flowlog3.html&quot;&gt;Part 3: Optimality&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/04/17/flowlog4.html&quot;&gt;Part 4: Verification&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/06/02/flowlog5.html&quot;&gt;Part 5: Differential Analysis&lt;/A&gt;&lt;BR&gt;
&lt;HR/&gt;

&lt;P&gt; Verification is a powerful way to make sure a program meets expectations,
but what if those expectations aren&apos;t written down, or the user lacks the
expertise to write formal properties? Flowlog supports a powerful form of
&lt;i&gt;property-free analysis&lt;/i&gt;: program differencing.

&lt;P&gt; When we make a program change, usually we&apos;re starting from a version that
&quot;works&quot;. We&apos;d like to transfer what confidence we had in the original version
to the new version, plus confirm our intuition about the changes. In other
words, even if the original program had bugs, we&apos;d like to at least confirm
that the edit doesn&apos;t introduce any new ones.

&lt;P&gt; Of course, taking the &lt;i&gt;syntactic&lt;/i&gt; difference of two programs is easy
&amp;mdash; just use &lt;tt&gt;diff&lt;/tt&gt;! &amp;mdash; but usually that&apos;s not good enough.
What we want is the behavioral, or &lt;i&gt;semantic&lt;/i&gt; difference. Flowlog
provides semantic differencing via Alloy, similarly to how it does property
checking. We call Flowlog&apos;s differencing engine Chimp (short for
&lt;B&gt;Ch&lt;/B&gt;ange-&lt;B&gt;imp&lt;/B&gt;act).

&lt;h4&gt;Differences in Output and State Transitions&lt;/h4&gt;

&lt;P&gt; Chimp translates both the old (&lt;tt&gt;prog1&lt;/tt&gt;) and new (&lt;tt&gt;prog2&lt;/tt&gt;)
versions to Alloy, then supports asking questions like: &lt;i&gt;Will the two
versions ever handle packets differently?&lt;/i&gt;

More generally, we can ask Chimp whether the program&apos;s output behavior ever
differs: does there exist some program state and input event such that, in
that state, the two programs will disagree on output? 

&lt;pre&gt;
pred changePolicyOut[st: State, ev: Event] {
  some out: Event |
    prog1/outpolicy[st,ev,out] &amp;&amp; not prog2/outpolicy[st,ev,out] ||
    prog2/outpolicy[st,ev,out] &amp;&amp; not prog1/outpolicy[st,ev,out]
}
&lt;/pre&gt;

Any time one program issues an output event that the other doesn&apos;t, Chimp
displays an Alloy scenario.

&lt;P&gt;
We might also ask: &lt;i&gt;When can the programs change state differently?&lt;/i&gt;
Similarly to &lt;tt&gt;changePolicyOut&lt;/tt&gt; above, Chimp defines
&lt;tt&gt;changeStateTransition[st: State, ev: Event]&lt;/tt&gt; as matching any of the
following for each table &lt;tt&gt;T&lt;/tt&gt; in the program:

&lt;pre&gt;
some x0, ..., xn: univ | 
  prog1/afterEvent_T[prestate, ev, x0, ..., xn] &amp;&amp; 
    not prog2/afterEvent_T[prestate, ev, x0, ..., xn] ||
  prog2/afterEvent_T[prestate, ev, x0, ..., xn] &amp;&amp; 
    not prog1/afterEvent_T[prestate, ev, x0, ..., xn]
&lt;/pre&gt;

&lt;P&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/04/13/flowlog4.html&quot;&gt;Recall&lt;/A&gt; that
&lt;tt&gt;afterEvent_T&lt;/tt&gt; keeps track of when each tuple is in the
table &lt;tt&gt;T&lt;/tt&gt; after an event is processed. 

&lt;h4&gt;Refining Differential Analysis&lt;/h4&gt;

&lt;P&gt;
The two predicates above are both built into Chimp. Using them as a starting
point, users can ask pointed questions about the effects of the change. For
instance, will any TCP packets be handled differently? Just search for a
pre-state and a TCP packet that the programs disagree on:

&lt;pre&gt;
some prestate: State, p: EVtcp_acket |
  changePolicyOut[prestate, p]
&lt;/pre&gt;

This lets users explore the consequences of their change without any formal
guidance except their intuition about what the change should do.

&lt;h4&gt;Reachability&lt;/h4&gt;

&lt;P&gt;
So far, these queries show scenarios where the programs differ, taking into
consideration all potential inputs and starting states; this includes
potentially unreachable starting states. We could, for instance, have two
programs that behave differently if a table is populated (resulting in a
non-empty semantic diff!) yet never actually insert rows into that table.
Chimp provides optional reachability-checking to counter this, although users
must cap the length of system traces being searched.

&lt;h4&gt;Schema Clashes&lt;/h4&gt;

&lt;P&gt;
Suppose that we want to modify the &lt;A
HREF=&quot;http://blog.brownplt.org/2014/09/30/flowlog1.html&quot;&gt;original
source-tracking example&lt;/A&gt; to keep
track of flows by source and destination, rather than just source addresses.
Now instead of one column:

&lt;pre&gt;
TABLE seen(macaddr);
&lt;/pre&gt;

the &lt;tt&gt;seen&lt;/tt&gt; table has &lt;i&gt;two&lt;/i&gt; columns:

&lt;pre&gt;
TABLE seen(macaddr, macaddr);
&lt;/pre&gt;

&lt;P&gt;
This poses a challenge for Chimp; what shape should the &lt;tt&gt;seen&lt;/tt&gt; table
be? If Chimp finds a scenario, should it show a &lt;tt&gt;seen&lt;/tt&gt; table with one
or two columns? We call this situation a &lt;i&gt;schema clash&lt;/i&gt;, and Chimp
addresses it by creating two separate tables in the prestate: one with one
column (used by the first program) and another with two columns (used by the
second program).

&lt;P&gt;
Doing this causes a new issue: Chimp searches for &lt;i&gt;arbitrary&lt;/i&gt; states
that satisfy the change-impact predicates. Since there is no constraint
between the values of the two tables, Chimp might return a scenario where
(say) the first &lt;tt&gt;seen&lt;/tt&gt; table is empty, but the second contains tuples! 

&lt;P&gt;
This doesn&apos;t match our intuition for the change: we expect that for every
source in the first table, there is a source-destination pair in the second
table, and vice versa. We can add this constraint to Chimp and filter the
scenarios it shows us, but first, we should ask whether that constraint
actually reflects the behavior of the two programs.

&lt;h4&gt;Differential Properties&lt;/h4&gt;

&lt;P&gt;
Since it&apos;s based on Flowlog&apos;s verification framework, Chimp allows us to check
properties stated over multiple programs. Our expecation above, stated in
Alloy for an arbitrary state &lt;tt&gt;s&lt;/tt&gt;, is:

&lt;pre&gt;
all src: Macaddr | 
  src in s.seen1 
  iff 
  some dst: Macaddr | src-&gt;dst in s.seen2
&lt;/pre&gt;

&lt;P&gt;
Let&apos;s check that this condition holds for all reachable states. We&apos;ll proceed
inductively. The condition holds trivially at the starting (empty) state; so
we only need to show that it is preserved as the program transitions. We
search for a counterexample:

&lt;pre&gt;
some prestate: State, ev: Event | {
  // prestate satisfies the condition
  all src: Macaddr | src in prestate.seen_1 iff 
    some dst: Macaddr | src-&gt;dst in prestate.seen_2
	
  // poststate does not
  some src: Macaddr | 
    (prog1/afterEvent_seen_1[prestate,ev,src] and 
     all dst: Macaddr | not prog2/afterEvent_seen_2[prestate,ev,src,dst])
    ||
    (not prog1/afterEvent_seen_1[prestate,ev,src] and 
     some dst: Macaddr | prog2/afterEvent_seen_2[prestate,ev,src,dst])
}
&lt;/pre&gt;

&lt;P&gt;
Chimp finds no counterexample. Unfortunately, Chimp can&apos;t guarantee that this
isn&apos;t a false negative; the query falls outside the class where Chimp can
guarantee a complete search. Nevertheless, the lack of counterexample serves
to increase our confidence that the change respects our intent. 

&lt;P&gt;
After adding the constraint that, for every source in the first table, there
is a source-destination pair in the second table, Chimp shows us that the new
program will change the state (to add a new destination) even if the source is
already in &lt;tt&gt;seen&lt;/tt&gt;.

&lt;h4&gt;Further Reading&lt;/h4&gt;

&lt;P&gt; Chimp supports more features than discussed here; for instance, Chimp can
compare the behavior of any number of program versions, but a two-program
comparison is the most common. You can read more about Chimp in &lt;A
href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/nfk-static-diff-
anal-sdn/&quot;&gt;our paper&lt;/A&gt;.
</content>
 </entry>
 
 <entry>
   <title>Tierless Programming for SDNs: Verification</title>
   <link href="http://blog.brownplt.org/2015/04/17/flowlog4.html"/>
   <updated>2015-04-17T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2015/04/17/flowlog4</id>
   <content type="html">&lt;style&gt;
@media only screen and (device-width: 768px) and (orientation: landscape) {
  .mobile-comment {
    display: block;
  }
}

@media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
  .mobile-comment {
    display: block;
  }
}

.mobile-comment {
  display: none;
}
&lt;/style&gt;


&lt;p&gt;
This post is part of our series about tierless network programming with Flowlog:&lt;br&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2014/09/30/flowlog1.html&quot;&gt;Part 1: Tierless Programming&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/03/01/flowlog2.html&quot;&gt;Part 2: Interfacing with External Events&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/04/13/flowlog3.html&quot;&gt;Part 3: Optimality&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/04/17/flowlog4.html&quot;&gt;Part 4: Verification&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/06/02/flowlog5.html&quot;&gt;Part 5: Differential Analysis&lt;/A&gt;&lt;BR&gt;
&lt;HR/&gt;

The last post said what it means for Flowlog&apos;s compiler to be &lt;i&gt;optimal&lt;/i&gt;,
which prevents certain bugs from ever occurring. But what about the program
itself? Flowlog has built-in features to help verify &lt;i&gt;program
correctness&lt;/i&gt;, independent of how the network is set up.

&lt;p&gt; To see Flowlog&apos;s program analysis in action, let&apos;s first expand our
watchlist program a bit more. Before, we just flooded packets for demo
purposes:

&lt;pre&gt;
DO forward(new) WHERE
    new.locPt != p.locPt;
&lt;/pre&gt;

Now we&apos;ll do something a bit smarter. We&apos;ll make the program learn which ports
lead to which hosts, and use that knowledge to avoid flooding when possible (this
is often called a &quot;learning switch&quot;):

&lt;pre&gt;
TABLE learned(switchid, portid, macaddr);
ON packet(pkt):
  INSERT (pkt.locSw, pkt.locPt, pkt.dlSrc) INTO learned;

  DO forward(new) WHERE
    learned(pkt.locSw, new.locPt, pkt.dlDst);
    OR
    (NOT learned(pkt.locSw, ANY, pkt.dlDst) AND
     pkt.locPt != new.locPt);
&lt;/pre&gt;

The &lt;tt&gt;learned&lt;/tt&gt; table stores knowledge about where addresses have been
seen on the network. If a packet arrives with a destination the switch has
seen before as a source, there&apos;s no need to flood! While this program is still
fairly naive (it will fail if the network has cycles in it) it&apos;s complex
enough to have a few interesting properties we&apos;d like to check. For instance,
if the &lt;tt&gt;learned&lt;/tt&gt; table ever holds multiple ports for the same switch
and address, the program will end up sending multiple copies of the same
packet. But can the program ever end up in such a state? Since the initial,
startup state is empty, this amounts to checking:

&lt;i&gt;&lt;center&gt;&quot;Can the program ever transition from a valid state (i.e., one
where every switch and address has at most one port in &lt;tt&gt;learned&lt;/tt&gt;) into
an invalid one?&quot;&lt;/center&gt;&lt;/i&gt;

&lt;H4&gt;Verifying Flowlog&lt;/H4&gt;

&lt;p&gt;Each Flowlog rule defines part of an &lt;i&gt;event-handling&lt;/i&gt; function saying how
the system should react to each packet seen. Rules compile to logical
implications that Flowlog&apos;s runtime interprets whenever a packet arrives.&lt;/p&gt;

&lt;A HREF=&quot;http://alloy.mit.edu/alloy/&quot;&gt;Alloy&lt;/A&gt; is a tool for analyzing
relational logic specifications. Since Flowlog rules compile to logic, it&apos;s
easy to describe in Alloy how Flowlog programs behave. In fact, Flowlog can
&lt;i&gt;automatically&lt;/i&gt; generate Alloy specifications that describe when and how
the program takes actions or changes its state.

&lt;p&gt;For example, omitting some Alloy-language foibles for clarity, here&apos;s how
Flowlog describes our program&apos;s forwarding behavior in Alloy.
&lt;pre&gt;
pred forward[st: State, p: EVpacket, new: EVpacket] {
  // Case 1: known destination
  (p.locSw-&gt;new.locPt-&gt;p.dlDst) in learned and
   (p.locSw-&gt;new.locPt) in switchHasPort and ...)
  or
  // Case 2: unknown destination
  (all apt: Portid | (p.locSw-&gt;apt-&gt;p.dlDst) not in learned and
   new.locPt != p.locPt and 
   (p.locSw-&gt;new.locPt) in switchHasPort and ...)
}
&lt;/pre&gt;
An Alloy &lt;tt&gt;pred&lt;/tt&gt;icate is either true or false for a given input. This one says
whether, in a given state &lt;tt&gt;st&lt;/tt&gt;, an arbitrary packet &lt;tt&gt;p&lt;/tt&gt; will be
forwarded as a new packet &lt;tt&gt;new&lt;/tt&gt; (containing the output port and any
header modifications).
It combines both forwarding rules together to construct a logical definition
of forwarding behavior, rather than just a one-way implication (as in the case
of individual rules).
&lt;/p&gt;

&lt;p&gt;
The automatically generated specification also contains other predicates that
say how and when the controller&apos;s state will change. For instance,
&lt;tt&gt;afterEvent_learned&lt;/tt&gt;, which says when a given entry will be present in
&lt;tt&gt;learned&lt;/tt&gt; after the controller processes a packet. An
&lt;tt&gt;afterEvent&lt;/tt&gt; predicate is automatically defined for every state table
in the program. &lt;/p&gt;

&lt;p&gt; Using &lt;tt&gt;afterEvent_Learned&lt;/tt&gt;, we can verify our goal: that whenever
an event &lt;tt&gt;ev&lt;/tt&gt; arrives, the program will never add a second entry
&lt;tt&gt;(sw, pt2,addr)&lt;/tt&gt; to &lt;tt&gt;learned&lt;/tt&gt;: &lt;/p&gt;

&lt;pre&gt;
assert FunctionalLearned {
  all pre: State, ev: Event |
    all sw: Switchid, addr: Macaddr, pt1, pt2: Portid |
      (not (sw-&gt;pt1-&gt;addr in pre.learned) or 
       not (sw-&gt;pt2-&gt;addr in pre.learned)) and
      afterEvent_learned[pre, ev, sw, pt1, addr] and
      afterEvent_learned[pre, ev, sw, pt2, addr] implies pt1 = pt2
}
&lt;/pre&gt;

&lt;hr&gt;
&lt;center&gt;&lt;p&gt; Alloy finds a counterexample scenario (in under a second): &lt;/p&gt;
        &lt;img src=&quot;/img/macl_counterex2.png&quot; width=100%&gt;&lt;/img&gt;&lt;/center&gt;
&lt;hr&gt;

&lt;p&gt;The scenario shows an arbitrary packet (&lt;tt&gt;L/EVpacket&lt;/tt&gt;; the
&lt;tt&gt;L/&lt;/tt&gt; prefix can be ignored) arriving at port 1 (&lt;tt&gt;L/Portid1&lt;/tt&gt;) on
an arbitrary switch (&lt;tt&gt;L/Switchid&lt;/tt&gt;). The packet has the same source and
destination MAC address (&lt;tt&gt;L/Macaddr&lt;/tt&gt;). Before the packet arrived, the
controller state had a single row in its &lt;tt&gt;learned&lt;/tt&gt; table; it had
previously learned that &lt;tt&gt;L/Macaddr&lt;/tt&gt; can be reached out port 0
(&lt;tt&gt;L/Portid1&lt;/tt&gt;). Since the packet is from the same address, but a
different port, it will cause the controller to add a second row to its
&lt;tt&gt;learned&lt;/tt&gt; table, violating our property.&lt;/p&gt;

&lt;p&gt;This situation isn&apos;t unusual if hosts are mobile, like laptops
on a campus network are. To fix this issue, we add a rule that removes
obsolete mappings from the table:&lt;/p&gt;

&lt;pre&gt;
DELETE (pkt.locSw, pt, pkt.dlSrc) FROM learned WHERE
  not pt = pkt.locPt;
&lt;/pre&gt;

Alloy confirms that the property holds of the modified program. We now know
that any reachable state of our program is valid.

&lt;/p&gt;

&lt;h4&gt;Verification Completeness&lt;/h4&gt;

&lt;p&gt; Alloy does &lt;i&gt;bounded&lt;/i&gt; verification: along with properties to check, we
provide concrete bounds for each datatype. We might say to check up to to 3
switches, 4 IP addresses, and so on. So although Alloy never returns a false
positive, it can in general produce false negatives, because it searches for
counterexamples only up to the given bounds.

Fortunately, for many useful properties, we can compute and assert a
&lt;i&gt;sufficient&lt;/i&gt; bound. In the property we checked above, a counterexample
needs only 1 &lt;tt&gt;State&lt;/tt&gt; (to represent the program&apos;s pre-state) and 1
&lt;tt&gt;Event&lt;/tt&gt; (the arriving packet), plus room for its contents (2
&lt;tt&gt;Macaddr&lt;/tt&gt;s for source and destination, etc.), along with 1
&lt;tt&gt;Switchid&lt;/tt&gt;, 2 &lt;tt&gt;Portid&lt;/tt&gt;s and 1 &lt;tt&gt;Macaddr&lt;/tt&gt; to cover the
possibly-conflicted entries in the state. So when Alloy says that the new
program satisfies our property, we can trust it.

&lt;H4&gt;Benefits of Tierlessness&lt;/H4&gt;

&lt;p&gt;Suppose we enhanced the POX version of this program (&lt;A HREF=&quot;http://blog.brownplt.org/2014/09/30/flowlog1.html&quot;&gt;Part 1&lt;/A&gt;)
to learn ports in the same way, and then wanted to check the same property.
Since the POX program explicitly manages flow-table rules, and the property
involves a mixture of packet-handling (what is sent up to the controller?) and
controller logic (how is the state updated?), checking the POX program would
mean accounting for those rules and how the controller updates them over time.
This isn&apos;t necessary for the Flowlog version, because rule updates are all
handled optimally by the runtime. This means that property checking is simpler:
there&apos;s no multi-tiered model of rule updates, just a model of the program&apos;s
behavior.&lt;/p&gt;

&lt;P&gt;
You can read more about Flowlog&apos;s analysis support in
&lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/nfsk-flowlog-tierless/&quot;&gt;our paper&lt;/a&gt;.

&lt;p&gt;
In the &lt;A HREF=&quot;/2015/06/02/flowlog5.html&quot;&gt;next post&lt;/A&gt;, we&apos;ll finish up this sequence on Flowlog by reasoning about
behavioral &lt;i&gt;differences&lt;/i&gt; between multiple versions of the same
program.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Tierless Programming for SDNs: Optimality</title>
   <link href="http://blog.brownplt.org/2015/04/13/flowlog3.html"/>
   <updated>2015-04-13T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2015/04/13/flowlog3</id>
   <content type="html">&lt;style&gt;
@media only screen and (device-width: 768px) and (orientation: landscape) {
  .mobile-comment {
    display: block;
  }
}

@media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
  .mobile-comment {
    display: block;
  }
}

.mobile-comment {
  display: none;
}
&lt;/style&gt;

&lt;p&gt;
This post is part of our series about tierless network programming with Flowlog:&lt;br&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2014/09/30/flowlog1.html&quot;&gt;Part 1: Tierless Programming&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/03/01/flowlog2.html&quot;&gt;Part 2: Interfacing with External Events&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/04/13/flowlog3.html&quot;&gt;Part 3: Optimality&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/04/17/flowlog4.html&quot;&gt;Part 4: Verification&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/06/02/flowlog5.html&quot;&gt;Part 5: Differential Analysis&lt;/A&gt;&lt;BR&gt;
&lt;HR/&gt;

Since packets can trigger controller-state updates and event output, you might
wonder exactly which packets a Flowlog controller needs to see. For instance,
a packet without a source in the watchlist will never alter the controller&apos;s state.
Does such a packet need to grace the controller at all? The answer is no.
In fact, there are only three conditions under which switch rules do not
suffice, and the controller must be involved in packet-handling:

&lt;ul&gt;
  &lt;li&gt; when the packet will cause a change in controller state;&lt;/li&gt;
  &lt;li&gt; when the packet will cause the controller to send an event; and &lt;/li&gt;
  &lt;li&gt; when the packet must be modified in ways that OpenFlow 1.0 does not support on switches.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Flowlog&apos;s compiler ensures the controller sees packets if and only if one of
these holds; the compiler is therefore optimal with respect to this list.
To achieve this, the compiler analyzes every packet-triggered statement
in the program. For instance, the INSERT statement above
will only change the state for packets with a source in the watchlist (a
condition made explicit in the WHERE clause) and without a source in the seen
table (implicit in Flowlog&apos;s logical semantics for INSERT). Only if both of
these conditions are met will the controller see a packet.

An optimal compiler prevents certain kinds of bugs from occurring: the
controller program will never miss packets that will affect its state, and it
will never receive packets it doesn&apos;t need. 

&lt;P&gt;
You can read more about Flowlog in 
&lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/nfsk-flowlog-tierless/&quot;&gt;our paper&lt;/a&gt;.

&lt;p&gt;
In the &lt;A HREF=&quot;/2015/04/17/flowlog4.html&quot;&gt;next post&lt;/A&gt;, we&apos;ll look at Flowlog&apos;s built-in verification support.
&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Tierless Programming for SDNs: Events</title>
   <link href="http://blog.brownplt.org/2015/03/01/flowlog2.html"/>
   <updated>2015-03-01T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2015/03/01/flowlog2</id>
   <content type="html">&lt;style&gt;
@media only screen and (device-width: 768px) and (orientation: landscape) {
  .mobile-comment {
    display: block;
  }
}

@media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
  .mobile-comment {
    display: block;
  }
}

.mobile-comment {
  display: none;
}
&lt;/style&gt;

&lt;p&gt;
This post is part of our series about tierless network programming with Flowlog:
&lt;A HREF=&quot;http://blog.brownplt.org/2014/09/30/flowlog1.html&quot;&gt;Part 1: Tierless Programming&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/03/01/flowlog2.html&quot;&gt;Part 2: Interfacing with External Events&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/04/13/flowlog3.html&quot;&gt;Part 3: Optimality&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/04/17/flowlog4.html&quot;&gt;Part 4: Verification&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/06/02/flowlog5.html&quot;&gt;Part 5: Differential Analysis&lt;/A&gt;&lt;BR&gt;
&lt;HR/&gt;

&lt;p&gt;
The &lt;A HREF=&quot;/2014/09/30/flowlog1.html&quot;&gt;last post&lt;/A&gt; introduced Flowlog, a tierless language for SDN controller programming.
You might be wondering, &quot;What can I write in Flowlog? How expressive is it?&quot;
To support both its proactive compiler and automated program analysis (more on
this in the next post) we deliberately limited Flowlog&apos;s expressive power.
There are no loops in the language, and no recursion.

Instead of trying to be universally expressive, Flowlog embraces the fact that
most programs don&apos;t run in a vacuum. A controller may need to interact with
other services, and developers may wish to re-use pre-existing code. To enable
this, Flowlog programs can call out to non-Flowlog libraries. The runtime uses
standard RPCs (Thrift) for inter-process communication, so existing programs
can be quickly wrapped to communicate with Flowlog.

Much like how Flowlog abstracts out switch-rule updates, it also hides the
details of inter-process communcation. To see this, let&apos;s enhance the
address-logger application with a watch-list that external programs can add
to. We need a new table (&quot;watchlist&quot;), populated by arriving &quot;watchplease&quot;
events that populate the table. Finally, we make sure only watched addresses
are logged:

&lt;pre&gt;
TABLE seen(macaddr);
TABLE watchlist(macaddr);
EVENT watchplease = {target: macaddr};

ON watchplease(w):
  INSERT (w.target) INTO watchlist;

ON packet(p):
  INSERT (p.dlSrc) INTO seen WHERE
    watchlist(p.dlSrc);
  DO forward(new) WHERE
    new.locPt != p.locPt;&lt;/pre&gt;

When the program receives a watchplease event (sent via RPC from an external
program) it adds the appropriate address to its watchlist.

&lt;h4&gt;Sending Events&lt;/h4&gt;

Flowlog programs can also send events. Suppose we want to notify some other
process when a watchlisted address is seen, and the process is listening on
TCP port 20000. We just declare a named pipe that carries notifications to
that port:

&lt;pre&gt;
EVENT sawaddress = {addr: macaddr};
OUTGOING sendaddress(sawaddress) THEN
  SEND TO 127.0.0.1:20000;&lt;/pre&gt;

and then write a notification to that pipe for appropriate packets:

&lt;pre&gt;
ON packet(p) WHERE watchlist(p.dlSrc):
  DO sendaddress(s) WHERE s.addr = p.dlSrc;&lt;/pre&gt;

&lt;h4&gt;Synchronous Communication&lt;/h4&gt;

The event system supports asynchronous communication, but Flowlog also allows
synchronous queries to external programs. It does this with a &lt;i&gt;remote state&lt;/i&gt;
abstraction. If we wanted to manage the watchlist remotely, rather than
writing &lt;pre&gt;TABLE watchlist(macaddr);&lt;/pre&gt; we would write:

&lt;pre&gt;
REMOTE TABLE watchlist(macaddr)
  FROM watchlist AT 127.0.0.1 20000
  TIMEOUT 10 seconds;&lt;/pre&gt;

which tells Flowlog it can obtain the current list by sending queries to port
20000. Since these queries are managed behind the scenes, the program doesn&apos;t
need to change&amp;mdash;as far as the programmer is concerned, a table is a table.
Finally, the timeout says that Flowlog can cache prior results for 10 seconds.

&lt;h4&gt;Interfacing External Programs with Flowlog&lt;/h4&gt;

Flowlog can interface with code in any language that supports &lt;A
href=&quot;https://thrift.apache.org/&quot;&gt;Thrift RPC&lt;/A&gt; (including C++, Java, OCaml,
and many others). To interact with Flowlog, one only needs to implement the
interface Flowlog requires: a function that accepts notifications and a
function that responds to queries. Other functions may also (optionally) send
notifications. Thrift&apos;s library handles the rest.

&lt;P&gt;
You can read more about Flowlog&apos;s events in 
&lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/nfsk-flowlog-tierless/&quot;&gt;our paper&lt;/a&gt;.

&lt;p&gt;
In the &lt;A HREF=&quot;/2015/04/13/flowlog3.html&quot;&gt;next post&lt;/A&gt;, we&apos;ll look at what it means for Flowlog&apos;s compiler to be &lt;i&gt;optimal&lt;i&gt;.
</content>
 </entry>
 
 <entry>
   <title>Tierless Programming for Software-Defined Networks</title>
   <link href="http://blog.brownplt.org/2014/09/30/flowlog1.html"/>
   <updated>2014-09-30T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2014/09/30/flowlog1</id>
   <content type="html">&lt;style&gt;
@media only screen and (device-width: 768px) and (orientation: landscape) {
  .mobile-comment {
    display: block;
  }
}

@media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
  .mobile-comment {
    display: block;
  }
}

.mobile-comment {
  display: none;
}
&lt;/style&gt;

&lt;p&gt;
This post is part of our series about tierless network programming with Flowlog:
&lt;A HREF=&quot;http://blog.brownplt.org/2014/09/30/flowlog1.html&quot;&gt;Part 1: Tierless Programming&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/03/01/flowlog2.html&quot;&gt;Part 2: Interfacing with External Events&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/04/13/flowlog3.html&quot;&gt;Part 3: Optimality&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/04/17/flowlog4.html&quot;&gt;Part 4: Verification&lt;/A&gt;&lt;BR&gt;
&lt;A HREF=&quot;http://blog.brownplt.org/2015/06/02/flowlog5.html&quot;&gt;Part 5: Differential Analysis&lt;/A&gt;&lt;BR&gt;
&lt;HR/&gt;

&lt;p&gt;
Network devices like switches and routers update their behavior in real-time.
For instance, a router may change how it forwards traffic to address an outage
or congestion. In a traditional network, devices use distributed protocols to
decide on mutually consistent behavior, but Software-Defined Networks (SDN)
operate differently. Switches are no longer fully autonomous agents, but instead
receive instructions from logically centralized &lt;i&gt;controller applications&lt;/i&gt;
running on separate hardware. Since these applications can be arbitrary
programs, SDN operators gain tremendous flexibility in customizing their
network.
&lt;/p&gt;
&lt;p&gt;
The most popular SDN standard in current use is &lt;a href=&quot;https://www.opennetworking.org/sdn-resources/onf-specifications/openflow&quot;&gt;OpenFlow&lt;/a&gt;. With OpenFlow,
Controller applications install persistent forwarding rules on the switches
that match on packet header fields and list actions to take on a match. These
actions can include header modifications, forwarding, and even sending packets
to the controller for further evaluation. When a packet arrives without a
matching rule installed, the switch defaults to sending the packet to the
controller for instructions.
&lt;/p&gt;
&lt;p&gt;
Let&apos;s write a small controller application. It should (1) record the addresses
of machines sending packets on the network and (2) cause each switch to
forward traffic by flooding (i.e., sending out on all ports except the arrival
port). This is simple enough to write in &lt;a href=&quot;http://www.noxrepo.org/pox/about-pox/&quot;&gt;POX&lt;/a&gt;, a controller platform for
Python. The core of this program is a function that reacts to packets as they
arrive at the controller (we have removed some boilerplate and
initialization):
&lt;/p&gt;
  &lt;pre&gt;def _handle_PacketIn (self, event):
    packet = event.parsed

    def install_nomore ():
      msg = of.ofp_flow_mod()
      msg.match = of.ofp_match(dl_src = packet.src)
      msg.buffer_id = event.ofp.buffer_id
      msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
      self.connection.send(msg)

    def do_flood ():
      msg = of.ofp_packet_out()
      msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
      msg.data = event.ofp
      msg.buffer_id = None
      msg.in_port = event.port
      self.connection.send(msg)

    self.seenTable.add(packet.src)
    install_nomore()
    do_flood()&lt;/pre&gt;
&lt;p&gt;
First, the controller records the packet&apos;s source in its internal table. Next,
the install_nomore function adds a rule to the switch saying that packets with
this source should be flooded. Once the rule is installed, the switch will not
send packets with the same source to the controller again. Finally, the
do_flood function sends a reply telling the switch to flood the packet.
&lt;/p&gt;
&lt;p&gt;
This style of programming may remind you of the standard three-tier
web-programming architecture. Much like a web program generates JavaScript or
SQL strings, controller programs produce new switch rules in real-time. One
major difference is that switch rules are much less expressive than
JavaScript, which means that less computation can be delegated to the
switches. A bug in a controller program can throw the entire network&apos;s
behavior off. But it&apos;s easy to introduce bugs when every program produces
switch rules in real-time, effectively requiring its own mini-compiler!
&lt;/p&gt;

&lt;h4&gt;SDN Programming Without Tiers&lt;/h4&gt;

&lt;p&gt;
We&apos;ve been working on a &lt;i&gt;tierless&lt;/i&gt; language for SDN controllers: Flowlog.
In Flowlog, you write programs as if the controller sees every packet, and
never have to worry about the underlying switch rules. This means that some
common bugs in controller/switch interaction can never occur, but it also
means that the programming experience is simpler. In Flowlog, our
single-switch address-monitoring program is just:
&lt;/p&gt;

&lt;pre&gt;TABLE seen(macaddr);
ON ip_packet(p):
  INSERT (p.dlSrc) INTO seen;
  DO forward(new) WHERE new.locPt != p.locPt;&lt;/pre&gt;
&lt;p&gt;
The first line declares a one-column database table, &quot;seen&quot;. Line 2 says that
the following two lines are triggered by IP packets. Line 3 adds those
packets&apos; source addresses to the table, and line 4 sends the packets out
all other ports.
&lt;/p&gt;
&lt;p&gt;
As soon as this program runs, the Flowlog runtime proactively installs switch
rules to match the current controller state and automatically ensures
consistency. As the controller sees more addresses, the switch sends fewer
packets back to the controller&amp;mdash;but this is entirely transparent to the
programmer, whose job is simplified by the abstraction of an all-seeing
controller.
&lt;/p&gt;
&lt;h4&gt;Examples and Further Reading&lt;/h4&gt;

&lt;p&gt;
Flowlog is good for more than just toy examples. We&apos;ve used Flowlog for many
different network applications: ARP-caching, network address translation, and
even mediating discovery and content-streaming for devices like Apple TVs. You
can read more about Flowlog and Flowlog applications in 
&lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/nfsk-flowlog-tierless/&quot;&gt;our paper&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The &lt;A HREF=&quot;/2015/03/01/flowlog2.html&quot;&gt;next post&lt;/A&gt; talks more about what you can use Flowlog to write, and also
see how Flowlog allows programs to call out to external libraries in other
languages.
&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>CS Student Work/Sleep Habits Revealed As Possibly Dangerously Normal</title>
   <link href="http://blog.brownplt.org/2014/06/14/sleep-habits.html"/>
   <updated>2014-06-14T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2014/06/14/sleep-habits</id>
   <content type="html">&lt;em style=&quot;color: gray; font-size: smaller&quot;&gt;
  Written by Jesse Polhemus, and originally posted at the &lt;a href=&quot;http://blog.cs.brown.edu/2014/06/09/cs-student-work-habits-revealed-possibly-dangerously-normal/&quot;&gt;Brown CS blog&lt;/a&gt;&lt;/em&gt;

&lt;p&gt;Imagine a first-year computer science concentrator (let’s call him Luis)
e-mailing friends and family back home after a few weeks with Brown Computer
Science (BrownCS). Everything he expected to be challenging is even tougher
than anticipated: generative recursion, writing specifications instead of
implementations, learning how to test his code instead of just writing it.
Worst of all is the workload. On any given night, he’s averaging –this seems
too cruel to be possible– no more than eight or nine hours of sleep.&lt;/p&gt;

&lt;p&gt; Wait, what?  Everyone knows that CS students don&apos;t get any sleep, so eight
or nine hours is out of the question. Or is it? Recent findings from PhD
student Joseph Gibbs Politz, adjunct professor Kathi Fisler, and professor
Shriram Krishnamurthi analyze when students completed tasks in two different
BrownCS classes, shedding interesting light on an age-old question: when do our
students work, and when (if ever) do they sleep? The question calls to mind a
popular conception of the computer scientist that Luis has likely seen in
countless movies and books:

&lt;ul&gt;

&lt;li&gt; Hours are late. (A recent poster to boardgames@lists.cs.brown.edu requests
a 2 PM start time in order to avoid being “ridiculously early” for
prospective players.) &lt;/li&gt;

&lt;li&gt; Sleep is minimal. BrownCS alumnus Andy Hertzfeld, writing about the early
days of Apple Computer in Revolution in the Valley, describes the “gigantic
bag of chocolate-covered espresso beans” and “medicinal quantities of
caffeinated beverages” that allowed days of uninterrupted coding.  &lt;/li&gt;

&lt;/ul&gt;
&lt;/p&gt;

&lt;h3&gt;Part 1: Deadline Experiments&lt;/h3&gt;

&lt;p&gt;
The story begins a few years before Luis’s arrival, when Shriram would
routinely schedule his assignments to be due at the 11:00 AM start of class.
“Students looked exhausted,” he remembers. “They were clearly staying up all
night in order to complete the assignment just prior to class.” 
&lt;/p&gt;

&lt;p&gt;
Initially, he moved the deadline to 2:00 AM, figuring that night owl students
would finish work in the early hours of the morning and then get some sleep.
This was effective, but someone pointed out that it was unfair to other
professors who taught earlier classes and were forced to deal with tired
students who had finished Shriram’s assignment but not slept sufficiently.
&lt;/p&gt;

&lt;p&gt;
“My final step,” he explains, “was to change deadlines to midnight. I also
began penalizing late assignments on a 24-hour basis instead of an hourly one.
This encourages students to get a full night’s sleep even if they miss a
deadline.”
&lt;/p&gt;

&lt;p&gt;
This was the situation when Luis arrives. The next task was to start measuring
the results.   
&lt;/p&gt;

&lt;h3&gt;Part 2: Tracking Events&lt;/h3&gt;

&lt;p&gt;
Shriram, Kathi, and Joe analyzed two of Shriram’s classes, CS 019 and CS 1730.
For each class, Luis must submit test suites at any time he chooses, then read
reviews of his work from fellow students. He then continues working on the
solution, eventually producing a final implementation that must be submitted
prior to the midnight deadline.
&lt;/p&gt;

&lt;h3&gt;Part 3: Reality And Mythology&lt;/h3&gt;

&lt;p&gt;
Given these parameters, what work and sleep patterns would you expect? We asked
professor Tom Doeppner to reflect on Luis and share his experience of working
closely with students as Director of Undergraduate Studies and Director of the
Master’s Program. “Do students work late? I know I get e-mail from students
at all hours of the night,” he says, “and I found out quickly that morning
classes are unpopular, which is why I teach in the afternoon. Maybe it’s
associated with age? I liked to work late when I was young, but I got out of
the habit in my thirties.”
&lt;/p&gt;

&lt;p&gt;
Asked about the possible mythologizing of late nights and sleeplessness, Tom
tells a story from his own teaching: “Before we broke up CS 169 into two
classes, the students had t-shirts made: ‘CS 169: Because There Are Only 168
Hours In A Week’. I think there’s definitely a widespread belief that you’re
not really working hard unless you’re pulling multiple all-nighters.”
&lt;/p&gt;

&lt;p&gt;
This doesn’t exactly sound like Luis’s sleep habits! Take a look at the
graphs below to see how mythology and reality compare.
&lt;/p&gt;

&lt;h3&gt;Part 4: Results And Conclusions&lt;/h3&gt;

&lt;p&gt;
The graphs below depict test suite submissions, with time displayed in six-hour
segments. For example, between 6 PM and the midnight deadline (“6-M”), 50 CS
173 students are submitting tests.  
&lt;/p&gt;

&lt;img src=&quot;/img/expected-submissions.png&quot;&gt;&lt;/img&gt;

&lt;p&gt;
This graph is hypothetical, showing Joe, Kathi, and Shriram’s expectations for
submission activity. They expected activity to be slow and increase steadily,
culminating in frantic late-night activity just before the deadline. Generally
taller “M-6” (midnight to 6 AM) bars indicate late-night work and a
corresponding flurry of submissions, followed by generally shorter “6-N” (6
AM to noon) bars when students tried to get a few winks in. Cumulatively, these
two trends depict the popular conception of the computer science student who
favors late hours and perpetually lacks sleep.
&lt;/p&gt;

&lt;img src=&quot;/img/cs019-graph.png&quot;&gt;&lt;/img&gt;
&lt;img src=&quot;/img/cs173-graph.png&quot;&gt;&lt;/img&gt;

&lt;p&gt; These graphs show actual submissions.  As expected, activity generally
increases over time and the last day contains the majority of submissions.
However, unexpectedly, the “N-6” (noon to 6 PM) and “6-M” (6 PM to
midnight) segments are universally the most active. In the case of the CS 173
graph, this morning segment contains far more submissions than any other of the
day’s three segments. In both of these graphs, the “M-6” (midnight to 6 AM)
segments are universally the least active, even the day the assignment is due.
For example, the final segment of this type, which represents the last
available span of early morning hours, is among the lowest of all segments,
with only ten submissions occurring. In contrast, the corresponding “6-N” (6
AM to noon) shows more than four times as many submissions, suggesting that
most students do their work before or after the pre-dawn hours but not during
them.  
&lt;/p&gt;

&lt;p&gt;
“I wouldn’t have expected that,” Joe comments. “I think of the stories
folks tell of when they work not lining up with that, in terms of staying up
late and getting up just in time for class. Our students have something
important to do at midnight other than work: they cut off their work before
midnight and do something else. For the majority it’s probably sleep, but it
could just be social time or other coursework. Either way, it’s an interesting
across-the-board behavior.”
&lt;/p&gt;

&lt;p&gt;
If word of these results gets out, what can Luis and his fellow students
expect? “People will realize,” Shriram says, “that despite what everyone
likes to claim, students even in challenging courses really are getting sleep,
so it’s okay for them to, too.” Joe agrees: “There isn’t so much work in CS
that you have to sacrifice normal sleeping hours for it.”
&lt;/p&gt;

&lt;p&gt; Luis, his family, and his well-rested classmates will undoubtedly be glad
to hear it. The only question is: will their own descriptions of their
work/sleep habits change to match reality, or are tales of hyper-caffeinated
heroics too tempting to resist?
&lt;/p&gt;

&lt;h3&gt;Appendix&lt;/h3&gt;

&lt;p&gt;The graphs above are simplified for readability, and aggregated into 6-hour
increments.  Below we include graphs of the raw data in 3-hour increments.
This shows that there is &lt;em&gt;some&lt;/em&gt; work going on from 12am-3am the night
before assignments are due, but essentially nothing from 3am-6am.&lt;/p&gt;

&lt;p&gt;In both of these classes, we were also performing &lt;a
href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/ppkf-ct-multi-stage-in-flow/&quot;&gt;experiments
on code review&lt;/a&gt;, so the raw data includes when students &lt;em&gt;read&lt;/em&gt; the
code reviews they received, in addition to when they submitted their work.
Since the review necessarily happens after submission, and the reading of the
review after that, we see many more “late” events for reading reviews.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;CS019 in 3-hour increments:&lt;/b&gt;&lt;/p&gt;
&lt;img src=&quot;/img/cs019-3-hour.png&quot; width=&quot;100%&quot;&gt;&lt;/img&gt;
&lt;p&gt;&lt;b&gt;CS173 in 3-hour increments:&lt;/b&gt;&lt;/p&gt;
&lt;img src=&quot;/img/cs173-3-hour.png&quot; width=&quot;100%&quot;&gt;&lt;/img&gt;

</content>
 </entry>
 
 <entry>
   <title>Parley: User Studies for Syntax Design</title>
   <link href="http://blog.brownplt.org/2014/04/01/var-vs-yar.html"/>
   <updated>2014-04-01T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2014/04/01/var-vs-yar</id>
   <content type="html">&lt;style&gt;
.compare-container {
  width: 100%;
  display: block;
}

.compare-left {
  width: 45%;
  float: left;
}
.compare-left pre {
  padding: .5em;
  margin: .5em;
}
.compare-right {
  width: 45%;
  float: right;
}
.compare-right pre {
  padding: .5em;
  margin: .5em;
}

&lt;/style&gt;



&lt;p&gt;Programming languages&apos; syntax choices have always been cause for
spirited, yet unresolvable, debate. Opinions and so-called best
practices dominate discussion, with little empirical evidence to
justify them. As part of the &lt;a href=&quot;http://www.pyret.org&quot;&gt;Pyret&lt;/a&gt;
project, we&apos;ve been performing one of the most comprehensive empirical
studies on programming language syntax.&lt;/p&gt;

&lt;p&gt;To recap some of the issues: Many languages repurpose plain English words
for keywords, and run afoul of the impedance mismatch between, for instance,
the dictionary meaning of &lt;code&gt;switch&lt;/code&gt; and its semantics within the
language (see &lt;a href=&quot;http://eric.ed.gov/?id=ED319373&quot;&gt;Language-Independent
Conceptual &quot;Bugs&quot; in Novice Programming&lt;/a&gt; for a much more detailed
discussion). Another alternative, using non-ASCII symbols which cannot have
their meaning conflated, is promising but doesn&apos;t work well with traditional
editors (APL, we&apos;re looking at you).&lt;/p&gt;

&lt;p&gt;We are, instead, evalauting the use of unconventional syntax motivated
by a &lt;em&gt;non-technical&lt;/em&gt;, &lt;em&gt;easily-interpreted&lt;/em&gt; lexicon. We
refer to these cohesive lexicons as &lt;em&gt;lingos&lt;/em&gt;, and have begun
experimenting with one lingo-based syntax for Pyret, which we call
&lt;em&gt;Parley&lt;/em&gt;. It is best to see the Parley lingo in action,
compared to the more traditional syntax in early versions of Pyret:&lt;/p&gt;

&lt;div class=&quot;compare-container&quot;&gt;
  &lt;div class=&quot;compare-left&quot;&gt;
&lt;label&gt;&lt;b&gt;Normal Pyret&lt;/b&gt;&lt;/label&gt;
&lt;pre&gt;
var sum = 0
var arr = [1,2,3,4,5,6,7,8]
for each(piece from arr):
  sum := sum + piece
end
&lt;/pre&gt;
  &lt;/div&gt;
  &lt;div class=&quot;compare-right&quot;&gt;
&lt;label&gt;&lt;b&gt;With Parley Lingo Enabled&lt;/b&gt;&lt;/label&gt;
&lt;pre&gt;
yar sum be 0
yar arr be [1,2,3,4,5,6,7,8]
fer each(piece of arr):
  sum now be sum + piece
end
&lt;/pre&gt;
  &lt;/div&gt;
&lt;div style=&quot;clear:both&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;While it should seem obvious to the casual reader that Parley lingo is
a strict improvement, this is not a substitute for empirical
evaluation. To this end, we have been running a rummy series of user
studies to validate the new syntax. Our latest experiments are testing
program comprehension using an aye-tracker. The results, which will be
submitted to the Principles of Pirate Lingo conference, are pending
clearance from our Aye Arr Bee.&lt;/p&gt;


</content>
 </entry>
 
 <entry>
   <title>Typechecking Uses of the jQuery Language</title>
   <link href="http://blog.brownplt.org/2014/01/17/typechecking-jquery.html"/>
   <updated>2014-01-17T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2014/01/17/typechecking-jquery</id>
   <content type="html">&lt;p&gt;
  Manipulating HTML via JavaScript is often a frustrating task: the
  APIs for doing so, known as the Document Object Model (or DOM), are
  implemented to varying degrees of fidelity across different
  browsers, leading to browser-specific workarounds that contort the
  code.  Worse, the APIs are too low-level: they amount to an
  &amp;ldquo;assembly language for trees&amp;rdquo;, allowing programmers to
  navigate from a node to its parent, children or adjacent siblings;
  add, remove, or modify a node at a time; etc.  And like assembly
  programming, these low-level operations are imperative and often
  error-prone.
&lt;/p&gt;

&lt;p&gt;
  Fortunately, developers have created libraries that abstract away
  from this low-level tedium to provide a powerful, higher-level API.
  The best-known example of these
  is &lt;a href=&quot;http://jquery.com&quot;&gt;jQuery&lt;/a&gt;, and its API is so
  markedly different from the DOM API that it might as well be its own
  language &amp;mdash; a domain-specific language for HTML manipulation.
&lt;/p&gt;

&lt;h4&gt;With great &lt;span style=&quot;text-decoration:
line-through;&quot;&gt;power&lt;/span&gt;language comes great responsibility&lt;/h4&gt;

&lt;p&gt;
Every language has its own idiomatic forms, and therefore has its own
characteristic failure modes and error cases.  Our group has been
studying various (sub-)languages of JavaScript&amp;mdash;
&lt;a href=&quot;https://blog.brownplt.org/2011/11/11/s5-javascript-semantics.html&quot;&gt;JS itself&lt;/a&gt;,
&lt;a href=&quot;https://blog.brownplt.org/2011/09/13/adsafety.html&quot;&gt;ADsafety&lt;/a&gt;,
&lt;a href=&quot;https://blog.brownplt.org/2013/08/19/incognito.html&quot;&gt;private browsing violations&lt;/a&gt;&amp;mdash;
so the natural question to ask is, &lt;em&gt;what can we do to analyze
  jQuery as a language?&lt;/em&gt;
&lt;/p&gt;


&lt;p&gt;This post takes a tour of the solution we have constructed to this
  problem.  In it, we will see how a sophisticated technique,
  a &lt;em&gt;dependent type system&lt;/em&gt;, can be specialized for the jQuery
  language in a way that:

&lt;ul&gt;
  &lt;li&gt;Retains decidable type-inference,&lt;/li&gt;
  &lt;li&gt;Requires little programmer annotation overhead,&lt;/li&gt;
  &lt;li&gt;Hides most of the complexity from the programmer, and yet&lt;/li&gt;
  &lt;li&gt;Yields non-trivial results.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Engineering such a system is challenging, and is aided by the fact
  that jQuery&amp;rsquo;s APIs are well-structured enough that we can
  extract a workable typed description of them.

&lt;h3&gt;What does a jQuery program look like?&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s get a feel for those idiomatic pitfalls of jQuery by looking
  at a few tiny examples.  We&amp;rsquo;ll start with a (seemingly) simple
  question: what does this one line of code do?&lt;/p&gt;

&lt;div&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.tweet span&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;With a little knowledge of the API, jQuery&amp;rsquo;s code is quite
  readable: get all the &lt;code&gt;&quot;.tweet span&quot;&lt;/code&gt; nodes, get
  their &lt;code&gt;next()&lt;/code&gt; siblings, and&amp;hellip;get the HTML code of
  the first one of them.  In general, a jQuery expression consists of
  three parts: a &lt;em&gt;initial query&lt;/em&gt; to select some nodes, a
  sequence of &lt;em&gt;navigational steps&lt;/em&gt; that select nearby nodes
  related to the currently selected set, and finally
  some &lt;em&gt;manipulation&lt;/em&gt; to retrieve or set data on those node(s).&lt;/p&gt;

&lt;p&gt;This glib explanation hides a crucial assumption: that there exist
  nodes in the page that match the initial selector in the first
  place!  So &lt;b&gt;&lt;em&gt;jQuery programs&amp;rsquo; behavior depends crucially on the
  structure of the pages in which they run.&lt;/em&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Given the example above, the following line of code should behave
  analogously:&lt;/p&gt;
&lt;div&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.tweet span&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p&gt;But it doesn&amp;rsquo;t&amp;mdash;it actually returns the concatenated
    text content of &lt;em&gt;all the selected nodes&lt;/em&gt;, rather than just
    the first.  So &lt;b&gt;&lt;em&gt;jQuery APIs have behavior that depends
    heavily on how many nodes are currently selected.&lt;/em&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Finally, we might try to manipulate the nodes by mapping a function
  across them via jQuery&amp;rsquo;s &lt;code&gt;each()&lt;/code&gt; method, and here we
  have a classic problem that appears in any language: we must ensure
  that the mapped function is only applied to the correct sorts of
  HTML nodes.&lt;/p&gt;



&lt;h3&gt;Our approach&lt;/h3&gt;
&lt;p&gt;The examples above give a quick flavor of what can go wrong:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The final manipulation might not be appropriate for the type of
  nodes actually in the query-set.&lt;/li&gt;
&lt;li&gt;The navigational steps might &amp;ldquo;fall off the edge of the
  tree&amp;rdquo;, navigating by too many steps and resulting in a vacuous query-set.&lt;/li&gt;
&lt;li&gt;The initial query might not match any nodes in the document, or
  match too many nodes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; Our tool of choice for resolving all these issues is a type system
  for JavaScript.  We&amp;rsquo;ve 
  &lt;a href=&quot;https://blog.brownplt.org/2013/08/19/incognito.html&quot;&gt;used such a
  system before&lt;/a&gt; to analyze the security of Firefox browser
  extensions.  The type system is quite sophisticated to handle
  JavaScript idioms precisely, and while we take advantage of that
  sophistication, we also completely hide the bulk of it from the
  casual jQuery programmer.&lt;/p&gt;

&lt;p&gt;To adapt our prior system for jQuery, we need two technical
insights: we define &lt;em&gt;multiplicities&lt;/em&gt;, a new kind that allows us
to approximate the &lt;em&gt;size of a query set&lt;/em&gt; in its type and ensure
that APIs are only applied to correctly-sized sets, and we
define &lt;em&gt;local structure&lt;/em&gt;, which allows developers to inform the
type system about the query-related parts of the page.  &lt;/p&gt;

&lt;h3&gt;Technical details&lt;/h3&gt;
&lt;h4&gt;Multiplicities&lt;/h4&gt;
&lt;p&gt;Typically, when type system designers are confronted with the need
  to keep track of the size of a collection, they turn to
  a &lt;em&gt;dependently typed&lt;/em&gt; system, where the type of a collection
  can depend on, say, a numeric value.  So &amp;ldquo;a list of five
  booleans&amp;rdquo; has a distinct type from &amp;ldquo;a list of six
  booleans&amp;rdquo;.  This is very precise, allowing some APIs to be
  expressed with exactitude.  It does come at a heavy cost: most
  dependent type systems lose the ability to infer types, requiring
  hefty programmer annotations.  But is all this precision necessary
  for jQuery?&lt;/p&gt;

&lt;p&gt;Examining jQuery&amp;rsquo;s APIs reveals that its behavior can be broken down
into five cases: methods might require their invocant query-set
  contain&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Zero elements of any type &lt;code&gt;T&lt;/code&gt;, writen &lt;code&gt;0&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;One element of some type &lt;code&gt;T&lt;/code&gt;, written &lt;code&gt;1&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Zero or one elements of some type &lt;code&gt;T&lt;/code&gt;, written &lt;code&gt;01&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;One or more elements of some type &lt;code&gt;T&lt;/code&gt;, written &lt;code&gt;1+&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Any number (zero or more) elements of some type &lt;code&gt;T&lt;/code&gt;, written &lt;code&gt;0+&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These cases effectively &lt;em&gt;abstract&lt;/em&gt; the exact size of a
  collection into a simple, finite approximation.  None of
  jQuery&amp;rsquo;s APIs actually care if a query set contains five or
  fifty elements; all the matters is that it contains one-or-more.
  And therefore our system can avoid the very heavyweight onus of a
  typical dependent type system, instead using this simpler
  abstraction without any loss of necessary precision.&lt;/p&gt;

&lt;p&gt;Moreover, we can
  manipulate these cases using &lt;em&gt;interval arithmetic&lt;/em&gt;: for
  example, combining one collection of zero-or-one elements with
  another collection containing exactly one element yields a
  collection of one-or-more elements: &lt;code&gt;01&amp;lt;T&amp;gt; + 1&amp;lt;T&amp;gt; =
  1+&amp;lt;T&amp;gt;&lt;/code&gt;.  This is just interval addition.&lt;/p&gt;

&lt;p&gt;jQuery&amp;rsquo;s APIs all effectively map some behavior across a queryset.
  Consider the &lt;code&gt;next()&lt;/code&gt; method: given a collection of at
  least one element, it transforms each element into at most one
  element (because some element might not have any next sibling).  The
  result is a collection of zero-or-more elements (if every element
  does not have a next sibling).
  Symbolically: &lt;code&gt;1+&amp;lt;01&amp;lt;T&amp;gt;&amp;gt = 0+&amp;lt;T&amp;gt;&lt;/code&gt;.  This
  is just interval multiplication.&lt;/p&gt;

&lt;p&gt;We can use these two operations to describe the types of all of
  jQuery&amp;rsquo;s APIs. For example, the &lt;code&gt;next()&lt;/code&gt; method can be
  given the type &lt;code&gt;Forall T, 1+&amp;lt;T&amp;gt; -&amp;gt;
  0+&amp;lt;@next&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt;


&lt;h4&gt;Local structure&lt;/h4&gt;
&lt;p&gt;Wait &amp;mdash; what&amp;rsquo;s &lt;code&gt;@next&lt;/code&gt;?  Recall that we need to
connect the type system to the content of the page.  So we ask
programmers to define &lt;em&gt;local structures&lt;/em&gt; that describe the
portions of their pages that they intend to query.  Think of them as
&amp;ldquo;schemas for page fragments&amp;rdquo;: while it is not reasonable
to ask programmers to schematize parts of the page they neither control
nor need to manipulate (such as 3&lt;sup&gt;rd&lt;/sup&gt;-party ads), they
certainly must know the structure of those parts of the page that they
  query!  A local structure for, say, a Twitter stream might say:&lt;/p&gt;

&lt;pre&gt;
(Tweet : Div classes = {tweet} optional = {starred}
   (Author : Span classes = {span})
   (Time : Span classes = {time})
   (Content : Span classes = {content})
&lt;/pre&gt;

&lt;p&gt;Read this as &amp;ldquo;A &lt;code&gt;Tweet&lt;/code&gt; is a &lt;code&gt;Div&lt;/code&gt;
  that definitely has class &lt;code&gt;tweet&lt;/code&gt; and might have
  class &lt;code&gt;starred&lt;/code&gt;.  It contains three children elements in order:
  an &lt;code&gt;Author&lt;/code&gt;, a &lt;code&gt;Time&lt;/code&gt;, and
  a &lt;code&gt;Content&lt;/code&gt;.  An &lt;code&gt;Author&lt;/code&gt; is
  a &lt;code&gt;Span&lt;/code&gt; with class &lt;code&gt;span&lt;/code&gt;&amp;hellip;&amp;rdquo;&lt;/p&gt;

&lt;p&gt;(If you are familiar with templating libraries
  like &lt;a href=&quot;http://mustache.github.io/&quot;&gt;mustache.js&lt;/a&gt;, these
  local structures might look familiar: they are just the widgets you
  would define for template expansion.)&lt;/p&gt;

&lt;p&gt;From these definitions, we can compute crucial relationships: for
  instance, the &lt;code&gt;@next&lt;/code&gt; sibling of an &lt;code&gt;Author&lt;/code&gt;
  is a &lt;code&gt;Time&lt;/code&gt;.  And that in turn completes our
  understanding of the type for &lt;code&gt;next()&lt;/code&gt; above: for
  any &lt;em&gt;local structure&lt;/em&gt;
  type &lt;code&gt;T&lt;/code&gt;, &lt;code&gt;next()&lt;/code&gt; can be called on a
  collection of &lt;em&gt;at least one &lt;code&gt;T&lt;/code&gt;&lt;/em&gt; and will
  return collection of &lt;em&gt;zero or more&lt;/em&gt; elements that are
  the &lt;code&gt;@next&lt;/code&gt; siblings of &lt;code&gt;T&lt;/code&gt;s.&lt;/p&gt;

&lt;p&gt;Note crucially that while the &lt;em&gt;uses&lt;/em&gt; of &lt;code&gt;@next&lt;/code&gt;
  are baked into our system, the function itself is &lt;em&gt;not&lt;/em&gt;
  defined once-and-for-all for all pages: it is computed from the
  local structures that the programmer defined.  In this way,
  we&amp;rsquo;ve parameterized our type system.  We imbue it with
  knowledge of jQuery&amp;rsquo;s fixed API, but leave a hole for programmers to
  provide their page-specific information, and
  thereby &lt;em&gt;specialize&lt;/em&gt; our system for their code.&lt;/p&gt;

&lt;p&gt;Of course, &lt;code&gt;@next&lt;/code&gt; is not the only function we compute
  over the local structure.  We can
  compute &lt;code&gt;@parent&lt;/code&gt;s, &lt;code&gt;@siblings&lt;/code&gt;, &lt;code&gt;@ancestors&lt;/code&gt;,
  and more.  But all of these functions are readily deducible from the
  local structure.&lt;/p&gt;


&lt;h3&gt;Ok, so what does this all do for me?&lt;/h3&gt;
Continuing with our Tweet example above, our system provides the
following output for these next queries:

&lt;div&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Mistake made: one too many calls to .next(), so the query set is empty&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.tweet&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;red&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// ==&amp;gt; ERROR: &apos;css&apos; expects 1+&amp;lt;Element&amp;gt;, got 0&amp;lt;Element&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Mistake made: one too few calls to .next(), so the query set is too big&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.tweet #myTweet&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// ==&amp;gt;; ERROR: &apos;css&apos; expects 1&amp;lt;Element&amp;gt;, got 1+&amp;lt;Author+Time&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Correct query&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.tweet #myTweet&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// ==&amp;gt; Typechecks successfully&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;/div&gt;

The paper contains additional examples, showing how the types progress
across more elaborate jQuery expressions.

&lt;h3&gt;The big picture&lt;/h3&gt;
&lt;p&gt;We have defined a set of types for the jQuery APIs that captures
  their intended behavior.  These types are expressed using helper
  functions such as &lt;code&gt;@next&lt;/code&gt;, whose behavior is specific to
  each page.  We ask programmers merely to define the local structures
  of their page, and from that we compute the helper functions we
  need.  And finally, from that, our system can produce type errors
  whenever it encounters the problematic situations we listed above.
  No additional programmer effort is needed, and the type errors
  produced are typically local and pertinent to fixing buggy code.&lt;/p&gt;


&lt;h3&gt;Further reading&lt;/h3&gt;
&lt;p&gt;Obviously we have elided many of the nitty-gritty details that make
  our system work.
  We&amp;rsquo;ve &lt;a href=&quot;http://cs.brown.edu/research/plt/dl/jquery/&quot;&gt;written
  up our full system&lt;/a&gt;, with more formal definitions of the types
  and worked examples of finding errors in buggy queries and
  successfully typechecking correct ones.  The writeup also explains
  some surprising subtleties of the type environment, and proposes
  some API enhancements to jQuery that were suggested by difficulties
  in engineering and using the types we defined.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Verifying Extensions' Compliance with Firefox's Private Browsing Mode</title>
   <link href="http://blog.brownplt.org/2013/08/19/incognito.html"/>
   <updated>2013-08-19T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2013/08/19/incognito</id>
   <content type="html">&lt;p&gt;
  All modern browsers now support a &amp;ldquo;private browsing mode&amp;rdquo;, in which
  the browser ostensibly leaves behind no traces on the user&apos;s file
  system of the user&apos;s browsing session.  This is quite subtle:
  browsers have to handle caches, cookies, preferences, bookmarks,
  deliberately downloaded files, and more.  So browser vendors have
  invested considerable engineering effort to ensure they have
  implemented it correctly.
&lt;/p&gt;

&lt;p&gt;
  Firefox, however, supports &lt;i&gt;extensions&lt;/i&gt;, which allow third
  party code to run with all the privilege of the browser itself.
  What happens to the security guarantee of private browsing mode,
  then?
&lt;/p&gt;

&lt;h3&gt;The current approach&lt;/h3&gt;
&lt;p&gt;
  Currently, Mozilla curates the collection of extensions, and any
  extension must pass through a manual code review to flag potentially
  privacy-violating behaviors.  This is a daunting and tedious task.
  Firefox contains well over 1,400 APIs, of which about twenty are
  obviously relevant to private-browsing mode, and another forty or so
  are less obviously relevant.  (It depends heavily on exactly what we
  mean by the privacy guarantee of &amp;ldquo;no traces left behind&amp;rdquo;: surely the
  browser should not leave files in its cache, but should it let users
  explicitly download and save a file?  What about adding or deleting
  bookmarks?)  And, if the APIs or definition of private-browsing
  policy ever change, this audit must be redone for each of the
  thousands of extensions.
&lt;/p&gt;

&lt;p&gt;
  The asymmetry in this situation should be obvious: Mozilla auditors
  should not have to reconstruct how each extension works; it should
  be &lt;i&gt;the extension developers&apos; responsibility&lt;/i&gt; to convince the
  auditor that their code complies with private-browsing guarantees.
  After all, they wrote the code!  Moreover, since auditors are
  fallible people, too, we should look to (semi-)automated tools to
  lower their reviewing effort.
&lt;/p&gt;

&lt;h3&gt;Our approach&lt;/h3&gt;

&lt;p&gt;
  So what property, ultimately, do we need to confirm about an
  extension&apos;s code to ensure its compliance?  Consider the pseudo-code
  below, which saves the current preferences to disk every few minutes:
&lt;/p&gt;

&lt;div&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;prefsObj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;thePrefsFile&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;autoSavePreferences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;inPivateBrowsingMode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// ...must store data only in memory...&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// ...allowed to save data to disk...&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;openFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;thePrefsFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prefsObj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tostring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;autoSafePreferences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;
  The key observation is that this code really defines &lt;i&gt;two
  programs&lt;/i&gt; that happen to share the same source code: one program
  runs when the browser is in private browsing mode, and the other
  runs when it isn&apos;t.  And &lt;i&gt;we simply do not care about one of those
  programs&lt;/i&gt;, because extensions can do whatever they&apos;d like when
  not in private-browsing mode.  So all we have to do is &amp;ldquo;disentangle&amp;rdquo;
  the two programs somehow, and confirm that the private-browsing
  version does not contain any file I/O.
&lt;/p&gt;

&lt;h4&gt;Technical insight&lt;/h4&gt;
&lt;p&gt;
  Our tool of choice for this purpose is a type system for JavaScript.
  We&apos;ve &lt;a href=&quot;https://blog.brownplt.org/2011/09/13/adsafety.html&quot;&gt;used such a
  system before&lt;/a&gt; to analyze the security of the ADsafe sandbox.
  The type system is quite sophisticated to handle JavaScript idioms
  precisely, but for our purposes here we need only part of its
  expressive power.  We need three pieces: first, three new types;
  second, specialized typing rules; and third, an appropriate type
  environment.

  &lt;ul&gt;
    &lt;li&gt;We define one new primitive type: &lt;code&gt;Unsafe&lt;/code&gt;.  We will
      ascribe this type to all the privacy-relevant APIs.&lt;/li&gt;
    &lt;li&gt;We use union types to define &lt;code&gt;Ext&lt;/code&gt;, the type of &amp;ldquo;all private-browsing-safe
      extensions&amp;rdquo;, namely: numbers, strings, booleans, objects
      whose fields are &lt;code&gt;Ext&lt;/code&gt;, and functions whose argument and return
      types are &lt;code&gt;Ext&lt;/code&gt;.  Notice that &lt;code&gt;Unsafe&lt;/code&gt; &amp;ldquo;doesn&amp;rsquo;t fit&amp;rdquo;
      into &lt;code&gt;Ext&lt;/code&gt;, so attempting to use an unsafe function, or
      pass it around in extension code, will result in a type
      error.&lt;/li&gt;
    &lt;li&gt;Instead of defining &lt;code&gt;Bool&lt;/code&gt; as a primitive type, we
      will instead define &lt;code&gt;True&lt;/code&gt; and &lt;code&gt;False&lt;/code&gt; as
    primitive types, and define &lt;code&gt;Bool&lt;/code&gt; as their union.&lt;/li&gt;
  &lt;/ul&gt;
  
  We&apos;ll also add two specialized typing rules:

  &lt;ul&gt;
    &lt;li&gt;If an expression has some union type, and only one component
      of that union actually typechecks, then we optimistically say
      that the expression typechecks even with the whole union type.
      This might seem very strange at first glance: surely, the
      expression &lt;code&gt;5(&quot;true&quot;)&lt;/code&gt; shouldn&apos;t typecheck?  But
      remember, our goal is to prevent privacy violations, and the
      code above will simply crash---it will never write to disk.  
      Accordingly, we &lt;i&gt;permit&lt;/i&gt; this code in our type system.&lt;/li&gt;
    &lt;li&gt;We add special rules for typechecking if-expressions.  When
      the condition typechecks at type &lt;code&gt;True&lt;/code&gt;, we only
      check the then-branch; when the condition typechecks at
      type &lt;code&gt;False&lt;/code&gt;, we only check the else-branch.
      (Otherwise, we check both branches as normal.)&lt;/li&gt;
  &lt;/ul&gt;

  Finally, we add the typing environment which initializes the whole
  system:

  &lt;ul&gt;
    &lt;li&gt;We give all the privacy-relevant APIs the
    type &lt;code&gt;Unsafe&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;We give the API &lt;code&gt;inPrivateBrowsingMode()&lt;/code&gt; the
    type &lt;code&gt;True&lt;/code&gt;.  Remember: we just don&apos;t care what happens
      when it&apos;s false!&lt;/li&gt;
  &lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
  Put together, what do all these pieces achieve?
  Because &lt;code&gt;Unsafe&lt;/code&gt; and &lt;code&gt;Ext&lt;/code&gt; are disjoint from
  each other, we can safely segregate any code into two pieces that
  cannot communicate with each other.  By carefully initializing the
  type environment, we make &lt;code&gt;Unsafe&lt;/code&gt; precisely delineate
  the APIs that extensions should not use in private browsing mode.
  The typing rules for if-expressions plus the type
  for &lt;code&gt;inPrivateBrowsingMode()&lt;/code&gt; amount to disentangling the
  two programs from each other: essentially, it implements dead-code
  elimination at type-checking time.  Lastly, the rule about union
  types makes the system much easier for programmers to use, since they
  do not have to spend any effort satisfying the typechecker about
  properties other than this privacy guarantee.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;In short&lt;/b&gt;, if a program passes our typechecker, then it must
  not call any privacy-violating APIs while in private-browsing mode,
  and hence is safe.  No audit needed!&lt;/p&gt;

&lt;h4&gt;Wait, what about exceptions to the policy?&lt;/h4&gt;

&lt;p&gt;Sometimes, extensions have good reasons for writing to disk even
  while in private-browsing mode.  Perhaps they&apos;re updating their
  anti-phishing blacklists, or they implement a download-helper that
  saves a file the user asked for, or they are a bookmark manager.  In
  such cases, there simply is no way for the code to typecheck.  As in
  any type system, we provide a mechanism to break out of the type
  system: an unchecked typecast.  We currently write such casts
  as &lt;code&gt;cheat(T)&lt;/code&gt;.  Such casts must be checked by a human
  auditor: they are explicitly marking the places where the extension
  is doing something unusual that must be confirmed.&lt;/p&gt;
&lt;p&gt;
  (In our original version, we took our cue from Haskell and wrote
  such casts as &lt;code&gt;unsafePerformReview&lt;/code&gt;, but sadly that is
  tediously long to write.)&lt;/p&gt;

&lt;h3&gt;But does it work?&lt;/h3&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;p&gt;We manually analyzed a dozen Firefox extensions that had already
  passed Mozilla&apos;s auditing process.  We annotated the extensions with
  as few type annotations as possible, with the goal of forcing the
  code to pass the typechecker, &lt;code&gt;cheat&lt;/code&gt;ing if necessary.
  These annotations &lt;b&gt;&lt;i&gt;found five extensions&lt;/i&gt;&lt;/b&gt; that violated
  the private-browsing policy: they could not be typechecked without
  using &lt;code&gt;cheat&lt;/code&gt;, and the unavoidable uses
  of &lt;code&gt;cheat&lt;/code&gt; pointed directly to where the extensions
  violated the policy.&lt;/p&gt;

&lt;h3&gt;Further reading&lt;/h3&gt;

&lt;p&gt;We&apos;ve &lt;a href=&quot;http://cs.brown.edu/research/plt/dl/incognito/&quot;&gt;written
  up our full system&lt;/a&gt;, with more formal definitions of the types
  and worked examples of the annotations needed.  The writeup also
  explains how we create the type environment in more detail, and what
  work is necessary to adapt this system to changes in the APIs or
  private-browsing implementation.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>From MOOC Students to Researchers</title>
   <link href="http://blog.brownplt.org/2013/06/18/moocs-for-research.html"/>
   <updated>2013-06-18T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2013/06/18/moocs-for-research</id>
   <content type="html">&lt;p&gt;Much has been written about MOOCs, including the potential for its
users to be treated, in effect, as research subjects: with tens of
thousands of users, patterns in their behavior will stand out starkly
with statistical significance. Much less has been written about using
MOOC participants as &lt;em&gt;researchers&lt;/em&gt; themselves. This is the
experiment we ran last fall, successfully.&lt;/p&gt;

&lt;p&gt;Our goal was to construct a &amp;ldquo;tested semantics&amp;rdquo;
for Python, a popular programming language. This requires some
explanation. A semantics is a formal description of the behavior of a
language so that, given any program, a user can precisely predict what
the program is going to do. A &amp;ldquo;tested&amp;rdquo; semantics is one
that is validated by checking it against real implementations of the
language itself (such as the ones that run on your computer).&lt;/p&gt;

&lt;p&gt;Constructing a tested semantics requires covering all of a large
language, carefully translating its every detail into a small core
language. Sometimes, a feature can be difficult to translate. Usually,
this just requires additional quantities of patience, creativity, or
elbow grease; in rare instances, it may require extending the core
language. Doing this for a whole real-world language is thus a
back-breaking effort.&lt;/p&gt;

&lt;p&gt;Our group has had some success building such semantics for multiple
languages and systems. In particular,
&lt;a href=&quot;https://blog.brownplt.org/2011/09/29/js-essence.html&quot;&gt;our semantics
for JavaScript&lt;/a&gt;
has come to be used widely. The degree of interest and rapidity of
uptake of that work made clear that there was interest in this
style of semantics for other languages, too. Python, which is not only
popular but also large and complex (much more so than JavaScript),
therefore seemed like an obvious next target. However, whereas the
first JavaScript effort (for version 3 of the language)
took a few months for a PhD student and an undergrad,
&lt;a href=&quot;https://blog.brownplt.org/2011/11/11/s5-javascript-semantics.html&quot;&gt;the second one&lt;/a&gt;
(focusing primarily on the strict-mode of version 5)
took far more effort (a post-doc, two PhD students, and a master&apos;s
student). JavaScript 5 approaches, but still doesn&apos;t match, the
complexity of Python. So the degree of resources we would need seemed
daunting.&lt;/p&gt;

&lt;p&gt;Crowdsourcing such an effort through, say, Mechanical Turk did not
seem very feasible (though we encourage someone else to try!). Rather,
we needed a trained workforce with some familiarity with the activity
of formally defining a programming language. In some sense,
&lt;a href=&quot;http://www.duolingo.com/&quot;&gt;Duolingo&lt;/a&gt; has a similar problem:
to be able to translate documents it needs people who know
languages. Duolingo addresses it by...teaching languages! In a similar
vein, our
&lt;a href=&quot;http://cs.brown.edu/courses/cs173/2012/OnLine/&quot;&gt;MOOC
on programming languages&lt;/a&gt; was going to serve the same purpose.
The MOOC would deliver a large and talented workforce; if we could
motivate them, we could then harness them to help perform the
research.&lt;/p&gt;

&lt;p&gt;During the semester, we therefore gave three assignments to get
students warmed up on Python:
&lt;a href=&quot;http://cs.brown.edu/courses/cs173/2012/Assignments/Python1&quot;&gt;1&lt;/a&gt;,
&lt;a href=&quot;http://cs.brown.edu/courses/cs173/2012/Assignments/Python2&quot;&gt;2&lt;/a&gt;, 
and
&lt;a href=&quot;http://cs.brown.edu/courses/cs173/2012/Assignments/Python3&quot;&gt;3&lt;/a&gt;.
By the end of these three assignments, all students in the class had
had some experience wrestling with the behavior of a real (and messy)
programming language, writing a definitional interpreter for its core,
desugaring the language to this core, and testing this desugaring
against (excerpts of) real test suites. The set of features was chosen
carefully to be both representative and attainable within the time of
the course.&lt;/p&gt;

&lt;p&gt;(To be clear, we didn&apos;t assign these projects only because we were
interested in building a Python semantics. We felt there would be
genuine value for our students in wrestling with these assignments. In
retrospect, however, this was too much work, and it
interfered with other pedagogic aspects of the course. As a result,
we&apos;re planning to shift this workload to a separate, half-course on
implementing languages.)&lt;/p&gt;

&lt;p&gt;Once the semester was over, we were ready for the real business to
begin. Based on the final solutions, we invited several students (out
of a much larger population of talent) to participate in taking the
project from this toy sub-language to the whole Python language. We
eventually ended up with an equal number of people who were Brown
students and who were from outside Brown. The three Brown students
were undergraduates; the three outsiders were an undergraduate
student, a professional programmer, and a retired IT professional who
now does triathlons. The three outsiders
were from Argentina, China, and India. The project was overseen by a
Brown CS PhD student.&lt;/p&gt;

&lt;p&gt;Even with this talented workforce, and the prior preparation done
through the course and creating the assignments prepared for the
course, getting the semantics to a reasonable state was a daunting
task. It is clear to us that it would have been impossible to produce
an equivalent quality artifact&amp;mdash;or to even come
close&amp;mdash;without this many people participating. As such, we feel
our strategy of using the MOOC was vindicated. The resulting paper has
just been accepted at a prestigious venue that was the most
appropriate one for this kind of work, with eight authors: the lead
PhD student, the three Brown undergrads, the three non-Brown people, and
the professor.&lt;/p&gt;

&lt;p&gt;A natural question is whether making the team even larger would
have helped. As we know from Fred Brooks&apos;s classic &lt;cite&gt;The Mythical
Man Month&lt;/cite&gt;, adding people to projects can often hurt rather than
help. Therefore, the determinant is to what extent the work can be
truly parallelized. Creating a tested semantics, as we did, has a fair
bit of parallelism, but we may have been reaching its limits. Other
tasks that have previously been crowdsourced&amp;mdash;such as looking for
stellar phenomena or trying to fold proteins&amp;mdash;are, as the
colloquial phrase has it, &amp;ldquo;embarrassingly parallel&amp;rdquo;. Most
real research problems are unlikely to have this property.&lt;/p&gt;

&lt;p&gt;In short, the participants of a MOOC don&apos;t only need to be thought
of as passive students. With the right training and motivation, they
can become equal members of a distributed research group, one that
might even have staying power over time. Also, participation in such a
project can help a person establish their research abilities even when
they are at some remove from a research center. Indeed, the foreign
undergraduate in our project will be coming to Brown as a master&apos;s
student in the fall!&lt;/p&gt;

&lt;p&gt;Would we do it again? For this fall, we discussed repeating the
experiment, and indeed considered ways of restructuring the course to
better support this goal. But before we do, we have decided to try to use
machine learning instead. Once again, machines may put people out of
work.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Social Ratings of Application Permissions (Part 4: The Goal)</title>
   <link href="http://blog.brownplt.org/2013/05/31/app-permssions-conclusion.html"/>
   <updated>2013-05-31T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2013/05/31/app-permssions-conclusion</id>
   <content type="html">&lt;p&gt;

(This is the fourth post in our series on Android application permissions. Click through for 
&lt;a href=&quot;https://blog.brownplt.org/2013/05/18/app-permissions-intro.html&quot;&gt;Part 1&lt;/a&gt;,
&lt;a href=&quot;https://blog.brownplt.org/2013/05/22/app-permssions-branding.html&quot;&gt;Part 2&lt;/a&gt;, and 
&lt;a href=&quot;https://blog.brownplt.org/2013/05/29/app-permissions-weather.html&quot;&gt;Part 3&lt;/a&gt;.)
	
&lt;/p&gt;

&lt;p&gt;
	
In this, the final post in our application permissions series, we&apos;ll discuss our trajectory 
for this research. Ultimately, we want to enable users to make informed decisions about the 
apps they install on their smartphones. Unfortunately, informed consent becomes difficult when 
you are asking users to make decisions in an area in which they have little expertise. Rating 
systems allow users to rely on the collective expertise of other users. 

&lt;/p&gt;

&lt;p&gt;
	
We intend to integrate permission ratings in to the app store in much the same way that functionality 
ratings are already there. This allows users to use visual cues they are already familiar with, such 
as the star rating that appears on the app page. 

&lt;/p&gt;


&lt;img src=&quot;/img/modified-app-page.png&quot; align=&quot;left&quot; width=&quot;288&quot; height=&quot;217&quot; alt=&quot;Modified main page&quot; style=&quot;border:2px solid grey&quot; HSPACE=&quot;20&quot; VSPACE=&quot;10&quot;/&gt;

&lt;p&gt;
	
We may also wish to convey to users how each individual permission is rated. This finer-grained 
information gives users the ability to make decisions in line with their own priorities. For example, 
if users are particularly concerned about the integrity of their email accounts, an app that has a 
low-rated email access permission may be unacceptable to a user, even if the app receives otherwise 
high scores for permissions. We can again leverage well-known visual cues to convey this information, 
perhaps with meters similar to password meters, as seen in the mock-up image below.

&lt;/p&gt;

&lt;img src=&quot;https://blog.brownplt.org/img/modified-perms.png&quot; align=&quot;right&quot; width=&quot;285&quot; height=&quot;228&quot; alt=&quot;Modified permissions page&quot; style=&quot;border:2px solid grey&quot; HSPACE=&quot;20&quot; VSPACE=&quot;10&quot;/&gt;

&lt;p&gt;
	
There are a variety of other features we may want to incorporate into a permission rating system: 
allowing users to select favorite or trusted raters could enable them to rely on a particularly savvy 
relative or friend. Additionally, users could build a privacy profile, and view ratings only from 
like-minded users. Side-by-side comparisons of different apps&apos; permissions rating could let users 
choose between similar apps more easily.

&lt;/p&gt;

&lt;p&gt;
	
Giving users an easy way to investigate app permissions will allow them to make privacy a part of their 
decision-making process without requiring extra work or research on their part. This will improve the 
overall security of using a smartphone (or other permission-rich device), leaving users less vulnerable 
to unintended sharing of their personal data.

&lt;/p&gt;

There&apos;s more! Click through to read
&lt;a href=&quot;https://blog.brownplt.org/2013/05/18/app-permissions-intro.html&quot;&gt;Part 1&lt;/a&gt;,
&lt;a href=&quot;https://blog.brownplt.org/2013/05/22/app-permssions-branding.html&quot;&gt;Part 2&lt;/a&gt;, and 
&lt;a href=&quot;https://blog.brownplt.org/2013/05/29/app-permissions-weather.html&quot;&gt;Part 3&lt;/a&gt;of the series!








</content>
 </entry>
 
 <entry>
   <title>Social Ratings of Application Permissions (Part 3: Permissions Within a Domain)</title>
   <link href="http://blog.brownplt.org/2013/05/29/app-permissions-weather.html"/>
   <updated>2013-05-29T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2013/05/29/app-permissions-weather</id>
   <content type="html">&lt;style&gt;
table { border-collapse: collapse; }
td { border: 1px solid #000; }
.one {
  background-image: -webkit-gradient(linear, left top, right top, from(#3BB9FF), to(white), color-stop(0.588, #3BB9FF), color-stop(0.588, white));
}
.two {
  background-image: -webkit-gradient(linear, left top, right top, from(#3BB9FF), to(white), color-stop(0.6, #3BB9FF), color-stop(0.6, white));
}

.three {
  background-image: -webkit-gradient(linear, left top, right top, from(#3BB9FF), to(white), color-stop(0.675, #3BB9FF), color-stop(0.675, white));
}

.four {
  background-image: -webkit-gradient(linear, left top, right top, from(#3BB9FF), to(white), color-stop(0.7, #3BB9FF), color-stop(0.7, white));
}

.five {
  background-image: -webkit-gradient(linear, left top, right top, from(#3BB9FF), to(white), color-stop(0.725, #3BB9FF), color-stop(0.725, white));
}

.six {
  background-image: -webkit-gradient(linear, left top, right top, from(#3BB9FF), to(white), color-stop(0.738, #3BB9FF), color-stop(0.738, white));
}

.seven {
  background-image: -webkit-gradient(linear, left top, right top, from(#3BB9FF), to(white), color-stop(0.758, #3BB9FF), color-stop(0.758, white));
}

.eight {
  background-image: -webkit-gradient(linear, left top, right top, from(#3BB9FF), to(white), color-stop(0.763, #3BB9FF), color-stop(0.763, white));
}

.nine {
  background-image: -webkit-gradient(linear, left top, right top, from(#3BB9FF), to(white), color-stop(0.765, #3BB9FF), color-stop(0.765, white));
}

.ten {
  background-image: -webkit-gradient(linear, left top, right top, from(#3BB9FF), to(white), color-stop(0.79, #3BB9FF), color-stop(0.79, white));
}

.eleven {
  background-image: -webkit-gradient(linear, left top, right top, from(#3BB9FF), to(white), color-stop(0.805, #3BB9FF), color-stop(0.805, white));
}

.twelve {
  background-image: -webkit-gradient(linear, left top, right top, from(#3BB9FF), to(white), color-stop(0.825, #3BB9FF), color-stop(0.825, white));
}

&lt;/style&gt;
  
  
&lt;p&gt;
	
(This is the third post in our series on Android application permissions. Click through for 
&lt;a href=&quot;https://blog.brownplt.org/2013/05/18/app-permissions-intro.html&quot;&gt;Part 1&lt;/a&gt;,
&lt;a href=&quot;https://blog.brownplt.org/2013/05/22/app-permssions-branding.html&quot;&gt;Part 2&lt;/a&gt;, and
&lt;a href=&quot;https://blog.brownplt.org/2013/05/31/app-permssions-conclusion.html&quot;&gt;Part 4&lt;/a&gt;.)


&lt;/p&gt;

&lt;p&gt;
	
In a &lt;a href=&quot;https://blog.brownplt.org/2013/05/18/app-permissions-intro.html&quot;&gt;prior post&lt;/a&gt; we 
discussed the potential value for a social rating system for smartphone apps. Such a system 
would give non-expert users some information about apps before installing them. Ultimately, 
the goal of such a system would be to help users choose between different apps with similar 
functionality (for an app they need) or decide if the payoff of an app is worth the potential 
risk of installing it (for apps they want). Both of these use cases would require conscientious 
ratings of permissions. 

&lt;/p&gt;

&lt;p&gt;
	
We chose to study this issue by considering the range of scores that respondents give to permissions. 
If respondents were not considering the permissions carefully, we would expect the score to be uniform 
across different permissions. We examined the top five weather forecasting apps in the Android 
marketplace: The Weather Channel, WeatherBug Elite, Acer Life Weather, WeatherPro, and AccuWeather 
Platinum.  We chose weather apps because they demonstrate a range of permission requirements; Acer Life 
Weather requires only four permissions while AccuWeather Platinum and WeatherBug Elite each require 
eleven permissions. We asked respondents to rate an app&apos;s individual permissions as either acceptable 
or unacceptable.

&lt;/p&gt;

&lt;p&gt;
	
Our findings, which we present in detail below, show that users will rate application permissions 
conscientiously. In short, we found that although the approval ratings for each permission are all 
over 50%, they vary significantly from permission to permission. Approval ratings for individual 
permissions ranged from 58.8% positive (for &amp;ldquo;Modify or delete the contents of your USB 
storage&amp;rdquo;) to 82.5% (for &amp;ldquo;Find accounts on the device&amp;rdquo;). The table at the bottom of 
this post shows the percentage of users who considered a given permission acceptable.
Because the ratings range from acceptable to unacceptable, they are likely representative of a given 
permissions&apos; risk (unlike uniformly positive or negative reviews). This makes them effective tools for users 
in determining which applications they wish to install on their phones.  
	
&lt;/p&gt;

&lt;p&gt;
	
Meaningful ratings tell us that it is possible to build a rating system for application permissions to 
accompany the existing system for functionality. In our next post, we&apos;ll discuss what such a system might 
look like!

&lt;/p&gt;

&lt;table style=&quot;width:600px&quot;&gt;
    &lt;tr&gt;
      &lt;td&gt;
        Modify or delete the contents of your USB storage
      &lt;/td&gt;
      &lt;td style=&quot;width:200px&quot; class=&quot;one&quot;&gt;
        58.8 %
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;
        Send sticky broadcast
      &lt;/td&gt;
      &lt;td style=&quot;width:200px&quot; class=&quot;two&quot;&gt;
        60 %
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;
        Control vibration
      &lt;/td&gt;
      &lt;td style=&quot;width:200px&quot; class=&quot;three&quot;&gt;
        67.5 %
      &lt;/td&gt;
    &lt;/tr&gt;   
    &lt;tr&gt;
      &lt;td&gt;
        View Wi-Fi connections
      &lt;/td&gt;
      &lt;td style=&quot;width:200px&quot; class=&quot;four&quot;&gt;
        70 %
      &lt;/td&gt;
    &lt;/tr&gt;   
    &lt;tr&gt;
      &lt;td&gt;
        Read phone status and identity
      &lt;/td&gt;
      &lt;td style=&quot;width:200px&quot; class=&quot;four&quot;&gt;
        70 %
      &lt;/td&gt;
    &lt;/tr&gt;    
    &lt;tr&gt;
      &lt;td&gt;
        Test access to protected storage
      &lt;/td&gt;
      &lt;td style=&quot;width:200px&quot; class=&quot;five&quot;&gt;
        72.5 %
      &lt;/td&gt;
    &lt;/tr&gt;    
    &lt;tr&gt;
      &lt;td&gt;
        Google Play license check
      &lt;/td&gt;
      &lt;td style=&quot;width:200px&quot; class=&quot;six&quot;&gt;
        73.8 %
      &lt;/td&gt;
    &lt;/tr&gt;    
    &lt;tr&gt;
      &lt;td&gt;
        Run at startup
      &lt;/td&gt;
      &lt;td style=&quot;width:200px&quot; class=&quot;seven&quot;&gt;
        75.8 %
      &lt;/td&gt;
    &lt;/tr&gt;    
    &lt;tr&gt;
      &lt;td&gt;
        Read Google service configuration
      &lt;/td&gt;
      &lt;td style=&quot;width:200px&quot; class=&quot;eight&quot;&gt;
        76.3 %
      &lt;/td&gt;
    &lt;/tr&gt;    
    &lt;tr&gt;
      &lt;td&gt;
        Full network access
      &lt;/td&gt;
      &lt;td style=&quot;width:200px&quot; class=&quot;nine&quot;&gt;
        76.5 %
      &lt;/td&gt;
    &lt;/tr&gt;    
    &lt;tr&gt;
      &lt;td&gt;
        Approximate location
      &lt;/td&gt;
      &lt;td style=&quot;width:200px&quot; class=&quot;ten&quot;&gt;
        79 %
      &lt;/td&gt;
    &lt;/tr&gt;    
    &lt;tr&gt;
      &lt;td&gt;
        View network connections
      &lt;/td&gt;
      &lt;td style=&quot;width:200px&quot; class=&quot;eleven&quot;&gt;
        80.5 %
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;
        Find accounts on the device
      &lt;/td&gt;
      &lt;td style=&quot;width:200px&quot; class=&quot;twelve&quot;&gt;
        82.5 %
      &lt;/td&gt;
    &lt;/tr&gt;
    
    
  &lt;/table&gt;

  There&apos;s more! Click through to read
  &lt;a href=&quot;https://blog.brownplt.org/2013/05/18/app-permissions-intro.html&quot;&gt;Part 1&lt;/a&gt;,
  &lt;a href=&quot;https://blog.brownplt.org/2013/05/22/app-permssions-branding.html&quot;&gt;Part 2&lt;/a&gt;, and 
  &lt;a href=&quot;https://blog.brownplt.org/2013/05/31/app-permssions-conclusion.html&quot;&gt;Part 4&lt;/a&gt; of the series!


  
  




</content>
 </entry>
 
 <entry>
   <title>Social Ratings of Application Permissions (Part 2: The Effect of Branding)</title>
   <link href="http://blog.brownplt.org/2013/05/22/app-permssions-branding.html"/>
   <updated>2013-05-22T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2013/05/22/app-permssions-branding</id>
   <content type="html">&lt;p&gt;

(This is the second post in this series. Click through for 
&lt;a href=&quot;https://blog.brownplt.org/2013/05/18/app-permissions-intro.html&quot;&gt;Part 1&lt;/a&gt; and 
&lt;a href=&quot;https://blog.brownplt.org/2013/05/29/app-permissions-weather.html&quot;&gt;Part 3&lt;/a&gt;, and 
&lt;a href=&quot;https://blog.brownplt.org/2013/05/31/app-permssions-conclusion.html&quot;&gt;Part 4&lt;/a&gt;.)

&lt;p&gt;
	
In a &lt;a href=&quot;https://blog.brownplt.org/2013/05/18/app-permissions-intro.html&quot;&gt;prior post&lt;/a&gt;, we 
introduced our experiments investigating user ratings of smartphone application permissions. 
In this post we&apos;ll discuss the effect that branding has on users&apos; evaluation of an app&apos;s 
permissions. Specifically, what effect does a brand name have on users&apos; perceptions and 
ratings of an app?

&lt;/p&gt;

&lt;p&gt;
	
We investigated this question using four well-known apps: Facebook, Gmail, Pandora Radio, and 
Angry Birds. Subjects were presented with a description of the app and its required permissions. 
We created surveys displaying the information presented to users in the Android app store, and 
asked users to rate the acceptability of the apps required permissions, and indicate whether 
they would install the app on their phone. Some of the subjects were presented with the true 
description of the app including its actual name, and the rest were presented with the same 
description, but with the well-known name replaced by a generic substitute. For example, Gmail 
was disguised as Mangogo Mail. 

&lt;/p&gt;

&lt;p&gt;
	
In the cases of Pandora and Angry Birds, there were no statistically significant differences in 
subjects&apos; responses between the two conditions. However, there were significant differences in the 
responses for Gmail and Facebook. 

&lt;/p&gt;

&lt;p&gt;
	
For Gmail, participants rated the generic version&apos;s permissions as less acceptable and were less 
likely to install that version. For Facebook, however, participants rated the permissions for the 
generic version as less acceptable, but it had no effect on whether subjects would install the app. 
These findings raise interesting questions. Are the differences in responses caused by privacy 
considerations or other concerns, such as ability to access existing accounts? Why are people more 
willing to install a less secure social network than an insecure email client?

&lt;/p&gt;

&lt;p&gt;
	
It is possible that people would be unwilling to install a generic email application because they 
want to be certain they could access their existing email or social network accounts. To separate 
access concerns from privacy concerns, we did a follow-up study in which we asked subjects to evaluate 
an app that was an interface over a brand-name app. In Gmail&apos;s case, for instance, subjects were 
presented with Gmore!, an app purporting to offer a smoother interaction with one&apos;s Gmail account. 

&lt;/p&gt;

&lt;p&gt;
	
Our findings for the interface apps was similar to the generic apps: for Facebook, subjects rated 
the permissions as less acceptable, but there was no effect on the likelihood of their installing 
the app; for Gmail, subjects rated the permissions as less acceptable and were less likely to install 
the app. In fact, the app that interfaced with Gmail had the lowest installation rate of any of the 
apps: just 47% of respondents would install the app, as opposed to 83% for brand-name Gmail, and 71% for 
generic Mangogo Mail. This suggests that subjects were concerned about the privacy of the apps, not just 
their functionality. 

&lt;/p&gt;

&lt;p&gt;
	
It is interesting that the app meant to interface with Facebook showed no significant difference in 
installation rates. Perhaps users are less concerned about the information on a social network than 
the information in their email, and see the potential consequences of installing an insecure social 
network as less dire than those associated with installing an insecure email client. This is just 
speculation, and this question requires further examination.

&lt;/p&gt;

&lt;p&gt;
	
Overall, it seems that branding may play a role in how users perceive a given app&apos;s permissions, 
depending on the app. We would like to examine the nuances of this effect in greater detail. Why 
does this effect occur in some apps but not others? When does the different perception of permissions 
affect installation rates and why? These questions are exciting avenues for future research!

&lt;/p&gt;

There&apos;s more! Click through to read 
&lt;a href=&quot;https://blog.brownplt.org/2013/05/18/app-permissions-intro.html&quot;&gt;Part 1&lt;/a&gt;,
&lt;a href=&quot;https://blog.brownplt.org/2013/05/29/app-permissions-weather.html&quot;&gt;Part 3&lt;/a&gt;, and 
&lt;a href=&quot;https://blog.brownplt.org/2013/05/31/app-permssions-conclusion.html&quot;&gt;Part 4&lt;/a&gt; of the series!





 









</content>
 </entry>
 
 <entry>
   <title>Social Ratings of Application Permissions (Part 1: Some Basic Conditions)</title>
   <link href="http://blog.brownplt.org/2013/05/18/app-permissions-intro.html"/>
   <updated>2013-05-18T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2013/05/18/app-permissions-intro</id>
   <content type="html">&lt;p&gt;
	
(This is the first post in our series on Android application permissions. Click through for 
&lt;a href=&quot;https://blog.brownplt.org/2013/05/22/app-permssions-branding.html&quot;&gt;Part 2&lt;/a&gt;,
&lt;a href=&quot;https://blog.brownplt.org/2013/05/29/app-permissions-weather.html&quot;&gt;Part 3&lt;/a&gt;, and 
&lt;a href=&quot;https://blog.brownplt.org/2013/05/31/app-permssions-conclusion.html&quot;&gt;Part 4&lt;/a&gt;.)

&lt;/p&gt;



&lt;p&gt;

Smartphones obtain their power from allowing users to install arbitrary apps 
to customize the device&amp;rsquo;s behavior. However, with this versatility comes risk 
to security and privacy.
	
&lt;/p&gt;


&lt;p&gt;

Different manufacturers have chosen to handle this problem in different ways. 
Android requires all applications to display their permissions to the user before 
being installed on the phone (then, once the user installs it, the application is 
free to use its permissions as it chooses). The Android approach allows users to 
make an informed decision about the applications they choose to install (and to do 
so at installation time, not in the midst of a critical task), but making this 
decision can be overwhelming, especially for non-expert users who may not even 
know what a given permission means. Many applications present a large number of 
permissions to users, and its not always clear why an application requires certain 
permissions. This requires users to gamble on how dangerous they expect a given 
application to be. 
	
&lt;/p&gt;


&lt;p&gt;
	
One way to help users is to rely on the expertise or experiences of other users, 
an approach that is already common in online marketplaces. Indeed, the Android 
application marketplace already allows users to rate applications. However, these 
reviews are meant to rate the application as a whole, and are not specific to the 
permissions required by the application. Therefore the overall star rating of an 
application is largely indicative of users&amp;rsquo; opinions of the functionality of an 
application, not the security of the application. When users do offer opinions 
about security and privacy, as they sometimes do, these views are buried in text 
and lost unless the user reads all the comments.
	
&lt;/p&gt;


&lt;p&gt;
	
Our goal is to make security and privacy ratings first-class members of the marketplace 
rating system. We have begun working on this problem, and will explain our preliminary 
results in this and a few more blog posts. All the experiments below were conducted on 
Mechanical Turk.

&lt;/p&gt;


&lt;p&gt;

In this post, we examine the following questions:
	&lt;ul&gt;
		&lt;li&gt;Will people even rate the app&apos;s permissions? Even when there are lots of permissions to rate?&lt;/li&gt;
		&lt;li&gt;
			Does users&amp;rsquo; willingness to install a given application change depending on when they are asked 
			to make this choice - before they&amp;rsquo;ve reflected on the individual permissions or after?
		&lt;/li&gt;
		&lt;li&gt;Do their ratings differ depending on how they were told about the app?&lt;/li&gt;
	&lt;/ul&gt;	

The short answers to these questions is: yes (and yes), not really, and not really. In 
later posts we will introduce some more interesting questions and explore their effects.
&lt;/p&gt;


&lt;p&gt;

We created surveys that mirrored the data provided by the Android installer (and as 
visible on the Google Play Web site). We examined four applications: Facebook, Gmail, 
Pandora, and Angry Birds. We asked respondents to rate the acceptability of the permissions 
required by each application and state whether they would install the application if they 
needed an app with that functionality.

&lt;/p&gt;


&lt;p&gt;
	
In the first condition, respondents were asked whether they would install the app before 
or after they were asked to rate the app&amp;rsquo;s individual permissions. In this case, only Angry 
Birds showed any distinction between the two conditions: Respondents were more likely to install 
the application if the were asked after they were asked to rate the permissions.&lt;br&gt;
	
Overall, however, the effect of asking before or after was very small; this is good, because it 
suggests that in the future we can ignore the overall rating, and it also offers some flexibility for 
interface design.

&lt;/p&gt;

&lt;p&gt;
	
The second condition was how the subject heard about the app (or rather, how they were asked to 
imagine they heard about it). Subjects were asked to imagine either that the app had been recommended 
to them by a colleague, that the app was a top &amp;ldquo;featured app&amp;rdquo; in the app store, or that the 
app was a top rated app in the app store. In this case, only Facebook showed any interesting results: 
respondents were less likely to install the application if it had been recommended by a colleague than 
if it was featured or highly rated. This result is particularly odd given that, due to the network effect 
of an app like Facebook, we would expect the app to be more valuable if friends or colleagues also use it. 
We would like to study this phenomenon further.&lt;br&gt;

Again, though this finding may be interesting, the fact that it has so little impact means we can set this 
condition aside in our future studies, thus narrowing the search space of factors that do affect how users 
rate permissions.

&lt;/p&gt;


&lt;p&gt;
	
That concludes this first post on this topic. In future posts we&amp;rsquo;ll examine the effect of branding, and 
present detailed ratings of apps in one particular domain. Stay tuned!

&lt;/p&gt;

&lt;p&gt;
	
&lt;b&gt;There&apos;s more! Click through to read 
&lt;a href=&quot;https://blog.brownplt.org/2013/05/22/app-permssions-branding.html&quot;&gt;Part 2&lt;/a&gt;,
&lt;a href=&quot;https://blog.brownplt.org/2013/05/29/app-permissions-weather.html&quot;&gt;Part 3&lt;/a&gt;, and 
&lt;a href=&quot;https://blog.brownplt.org/2013/05/31/app-permssions-conclusion.html&quot;&gt;Part 4&lt;/a&gt; of the series!

&lt;/p&gt;








</content>
 </entry>
 
 <entry>
   <title>Aluminum: Principled Scenario Exploration Through Minimality</title>
   <link href="http://blog.brownplt.org/2013/05/13/aluminum.html"/>
   <updated>2013-05-13T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2013/05/13/aluminum</id>
   <content type="html">&lt;style&gt;
@media only screen and (device-width: 768px) and (orientation: landscape) {
  .mobile-comment {
    display: block;
  }
}

@media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
  .mobile-comment {
    display: block;
  }
}

.mobile-comment {
  display: none;
}
&lt;/style&gt;

&lt;p&gt;
Software artifacts are hard to get right. Not just programs, but
protocols, configurations, etc. as well! Analysis tools can help
mitigate the risk at every stage in the development process.
&lt;/p&gt;

&lt;p&gt;
Tools designed for &lt;i&gt;scenario-finding&lt;/i&gt; produce examples of how an
artifact can behave in practice.  Scenario-finders often allow the
results to be targeted to a desired output or test a particular
portion of the artifact&amp;mdash;e.g., producing counterexamples that disprove
an assumption&amp;mdash;and so they are fundamentally different from most forms
of testing or simulation. Even better, concrete scenarios appeal to
the intuition of the developer, revealing corner-cases and potential
bugs that may never have been considered.
&lt;/p&gt;

&lt;h3&gt;Alloy&lt;/h3&gt; 


&lt;p&gt;
The &lt;A href=&quot;http://alloy.mit.edu/alloy/&quot;&gt;Alloy Analyzer&lt;/A&gt; is a
popular light-weight scenario-finding tool.  Let&apos;s look at at a small
example: a (partial) specification of the Java type system that is
included in the Alloy distribution. The explanations below each
portion are quoted from comments in the example&apos;s source file.
&lt;/p&gt;

&lt;pre&gt;abstract sig Type {subtypes: set Type}
sig Class, Interface extends Type {}
one sig Object extends Class {}
sig Instance {type: Class}
sig Variable {holds: lone Instance, type: Type}&lt;/pre&gt;

&lt;center&gt;&lt;i&gt;Each type is either a class or an interface, and each has a
set of subtypes. The Object class is unique. Every instance has a
creation type. Each variable has a declared type and may (but need
not) hold an instance.&lt;/i&gt;&lt;/center&gt;

&lt;pre&gt;fact TypeHierarchy {
  Type in Object.*subtypes
  no t: Type | t in t.^subtypes
  all t: Type | lone t.~subtypes &amp; Class
}

fact TypeSoundness {
  all v: Variable | v.holds.type in v.type.*subtypes
}
&lt;/pre&gt;
&lt;center&gt;&lt;i&gt;These facts say that (1) every type is a direct or indirect
subtype of Object; (2) no type is a direct or indirect subtype of
itself; (3) every type is a subtype of at most one class; and (4) all
instances held by a variable have types that are direct or indirect
subtypes of the variable&apos;s declared type. &lt;/i&gt;&lt;/center&gt;

&lt;p&gt;
Alloy will let us examine how the model can behave, up to
user-provided constraints. We can tell Alloy to show us scenarios that
also meet some additional constraints:
&lt;/p&gt;

&lt;pre&gt; run {
  some Class - Object
  some Interface
  some Variable.type &amp; Interface
  } for 4&lt;/pre&gt;

&lt;center&gt;&lt;i&gt;We read this as: &quot;Find a scenario in which (1) there is a
class distinct from Object; (2) there is some interface; and (3) some
variable has a declared type that is an interface.&quot;&lt;/i&gt;&lt;/center&gt;



&lt;p&gt; Alloy always checks for scenarios up to a finite bound on each
top-level type&amp;mdash;4 in this case. Here is the one that Alloy gives:
&lt;/p&gt;

&lt;figure&gt;
&lt;img class=&quot;center&quot; width=&quot;60%&quot; src=&quot;/img/javatypes-alloy-1.png&quot;&gt;
&lt;figcaption&gt;
  Alloy&apos;s first scenario
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;
This scenario illustrates a possible instance of the Java type
system. It&apos;s got one class and one interface definition; the interface
extends &lt;TT&gt;Object&lt;/TT&gt; (by default), and the class implements the
interface. There are two instances of that class. &lt;TT&gt;Variable0&lt;/TT&gt; and
&lt;TT&gt;Variable1&lt;/TT&gt; both hold &lt;TT&gt;Instance1&lt;/TT&gt;,
and &lt;TT&gt;Variable2&lt;/TT&gt; holds &lt;TT&gt;Instance0&lt;/TT&gt;.
&lt;/p&gt;

&lt;p&gt;
Alloy provides a &lt;B&gt;&lt;TT&gt;Next&lt;/TT&gt;&lt;/B&gt; button that will give us more examples,
when they exist. If we keep clicking it, we get a parade of hundreds
more:
&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;figure&gt;
&lt;img class=&quot;center&quot; width=&quot;100%&quot; src=&quot;/img/javatypes-alloy-2.png&quot;&gt;
&lt;figcaption&gt;
  Another Scenario
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;figure&gt;
&lt;img class=&quot;center&quot; width=&quot;100%&quot; src=&quot;/img/javatypes-alloy-3.png&quot;&gt;
&lt;figcaption&gt;
  Yet Another Scenario
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;figure&gt;
&lt;img class=&quot;center&quot; width=&quot;100%&quot; src=&quot;/img/javatypes-alloy-4.png&quot;&gt;
&lt;figcaption&gt;
  Still Another Scenario...
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/figure&gt;

&lt;p&gt;
Even a small specification like this one, with a relatively small size
bound (like 4), can yield many hundreds of
scenarios. That&apos;s &lt;i&gt;after&lt;/i&gt; Alloy has automatically ruled out lots
of superfluous scenarios that would be isomorphic to those already
seen. Scenario-overload means that the pathological examples--the
ones that the user needs to see--may be buried beneath many normal
ones.
&lt;/p&gt;

&lt;p&gt;
In addition, the order in which scenarios appear is up to the internal
SAT-solver that Alloy uses. There is no way for a user to direct which
scenario they see next without stopping their exploration, returning
to the specification, adding appropriate constraints, and starting the
parade of scenarios afresh.  What if we could reduce the hundreds of
scenarios that Alloy gives down to just a few, each of which
represented many other scenarios in a precise way? What if we could
let a user&apos;s goals guide their exploration without forcing a restart?
It turns out that we can.
&lt;/p&gt;

&lt;h3&gt;Aluminum: Beyond the &lt;B&gt;&lt;TT&gt;Next&lt;/TT&gt;&lt;/B&gt; Button&lt;/h3&gt;

&lt;p&gt;
We have created a modified version of Alloy that we
call &lt;u&gt;Aluminum&lt;/u&gt;. Aluminum produces fewer, more concise scenarios
and gives users additional control over their exploration. Let&apos;s look
at Aluminum running on the same example as before, versus the first
scenario that Alloy returned:
&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;figure&gt;
&lt;img class=&quot;center&quot; width=&quot;75%&quot; src=&quot;/img/javatypes-alloy-1.png&quot;&gt;
&lt;figcaption&gt;
  For reference: &lt;br&gt;The 1st Scenario from &lt;b&gt;Alloy&lt;/b&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;figure&gt;
&lt;img class=&quot;center&quot; width=&quot;75%&quot; src=&quot;/img/javatypes-aluminum-1.png&quot;&gt;
&lt;figcaption&gt;
  The 1st Scenario from &lt;b&gt;Aluminum&lt;/b&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;
Compared to the scenario that Alloy produced, this one is quite
small. That&apos;s not all, however: Aluminum guarantees that it
is &lt;i&gt;minimal&lt;/i&gt;: nothing can be removed from it without violating
the specification! Above and beyond just seeing a smaller concrete
example, a minimal scenario embodies necessity and gives users a
better sense of the dependencies in the specification.
&lt;/p&gt;

&lt;p&gt;
There are usually far fewer minimal scenarios than scenarios
overall. If we keep clicking &lt;B&gt;&lt;TT&gt;Next&lt;/TT&gt;&lt;/B&gt;, we get:
&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;figure&gt;
&lt;img class=&quot;center&quot; width=&quot;75%&quot; src=&quot;/img/javatypes-aluminum-2.png&quot;&gt;
&lt;figcaption&gt;
  The 2nd Minimal Scenario
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;figure&gt;
&lt;img class=&quot;center&quot; width=&quot;75%&quot; src=&quot;/img/javatypes-aluminum-3.png&quot;&gt;
&lt;figcaption&gt;
  The 3rd Minimal Scenario
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/figure&gt;

&lt;p&gt;
Asking for a 4th scenario via &lt;B&gt;&lt;TT&gt;Next&lt;/TT&gt;&lt;/B&gt; results in an error. That&apos;s
because in this case, there are only three minimal scenarios.
&lt;/p&gt;

&lt;h4&gt;What if...?&lt;/h4&gt;

&lt;p&gt;
Alloy&apos;s random, rich scenarios may contain useful information that
minimal scenarios do not. For instance, the Alloy scenarios we saw
allowed multiple variables to exist and classes to be
instantiated. None of the minimal scenarios illustrate these
possibilities.
&lt;/p&gt;

&lt;p&gt;
Moreover, a torrent of scenarios--minimal or otherwise--doesn&apos;t
encourage a user to really explore what can happen.  After seeing a
scenario, a user may ask whether various changes are possible. For
instance, &quot;Can I add another variable to this scenario?&quot;  More subtle
(but just as important) is: &quot;&lt;i&gt;What happens &lt;/i&gt; if I add another
variable?&quot; Aluminum can answer that question.
&lt;/p&gt;

&lt;p&gt;
To find out, we instruct Aluminum to try &lt;i&gt;augmenting&lt;/i&gt; the
starting scenario with a new variable. Aluminum produces a fresh
series of scenarios, each of which illustrates a way that that the
variable can be added:
&lt;/p&gt;
&lt;figure&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;img class=&quot;center&quot; width=&quot;100%&quot; src=&quot;/img/javatypes-aluminum-1+newvar.png&quot;&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;img class=&quot;center&quot; width=&quot;100%&quot; src=&quot;/img/javatypes-aluminum-1+newvar2.png&quot;&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;img class=&quot;center&quot; width=&quot;100%&quot; src=&quot;/img/javatypes-aluminum-1+newvar3.png&quot;&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;figcaption&gt;
  The Three Augmented Scenarios &lt;BR&gt;
  (The newly added variable is &lt;B&gt;&lt;TT&gt;Variable0&lt;/TT&gt;&lt;/B&gt;.)
&lt;/figcaption&gt;


&lt;/figure&gt;

&lt;p&gt;
From these, we learn that the new variable must have a type. In fact,
these new scenarios cover the three possible types that the variable
can receive.
&lt;/p&gt;

&lt;p&gt;
It&apos;s worth mentioning that the three augmented scenarios are actually
minimal themselves, just over a more restricted space&amp;mdash;the scenarios
containing the original one, plus an added variable. This ensures that
the consequences shown are all truly necessary.
&lt;/p&gt;

&lt;h4&gt;More Information&lt;/h4&gt;

&lt;p&gt;
To learn more about Aluminum, see our paper and watch our
video &lt;A href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/nsfdk-aluminum-scen-expl-min/&quot;&gt;here&lt;/A&gt;
or download the tool &lt;A href=&quot;http://cs.brown.edu/research/plt/dl/aluminum/&quot;&gt;here&lt;/A&gt;.
&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>A Privacy-Affecting Change in Firefox 20</title>
   <link href="http://blog.brownplt.org/2013/04/10/private-browsing-changes.html"/>
   <updated>2013-04-10T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2013/04/10/private-browsing-changes</id>
   <content type="html">&lt;p&gt;
Attention, privacy-conscious Firefox users!  Firefox
has supported private browsing mode (PBM) for a long time, and
Mozilla&apos;s guidelines for manipulating privacy sensitive data have not
changed...but the implementation of PBM has, with potentially
surprising consequences.  Previously innocent extensions may now be
leaking private browsing information.  Read on for details.&lt;/p&gt;

&lt;h3&gt;Global Private-Browsing Mode: Easy!&lt;/h3&gt;
&lt;p&gt;
In earlier versions of Firefox, PBM was an all-or-nothing affair:
either all currently open windows were in private mode, or none of
them were.  This made handling sensitive data easy; the essential
logic for privacy-aware extensions is simply:
&lt;/p&gt;

&lt;div&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;inPBM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;must&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;only&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;memory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;allowed&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;save&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;disk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;
(For the technically curious reader, there were some additional steps
to take if extension code used shared modules: they additionally had
to listen to events signalling exit from PBM, to flush any sensitive
data from memory.  This was not terribly hard; trying to &quot;do the right
thing&quot; would generally work.)
&lt;/p&gt;

&lt;h3&gt;Per-window Private Browsing: Trickier!&lt;/h3&gt; 
&lt;p&gt;
However, in Firefox 20, PBM is now a &lt;i&gt;per-window&lt;/i&gt; setting.  This
means that both public and private windows can be open simultaneously.
Now, the precautions above are not sufficient.  Consider a
session-management extension, that periodically saves all open windows
and tabs:
&lt;/p&gt;

&lt;div&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;   &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setInterval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;inPBM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;allWindowsAndTabs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;enumerateAllWindowsAndTabs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;allWindowsAndTabs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;
Most likely, this code internally uses Firefox&apos;s
&lt;code&gt;nsIWindowMediator&lt;/code&gt; API to produce the enumeration.  The
trouble is, that API does exactly what it claims: it enumerates
&lt;i&gt;all&lt;/i&gt; windows&amp;mdash;public and private&amp;mdash;regardless of the
privacy status of the calling window.  In particular, suppose that
both public and private windows were open simultaneously, and the
callback above ran in one of the public windows.  Then
&lt;code&gt;inPBM&lt;/code&gt; would be &lt;i&gt;false&lt;/i&gt;, and so the rest of the
function would continue, enumerate all windows, and save them: a clear
violation of private browsing, even though no code was running in the
private browsing windows!
&lt;/p&gt;
&lt;p&gt;
This code was &lt;i&gt;perfectly safe&lt;/i&gt; in earlier versions of
Firefox, because the possibility of having private and public windows
open simultaneously just could not occur.  This example demonstrates
the need to carefully audit interactions between seemingly unrelated
APIs, features, and modes&amp;mdash;ideally, mechanically.
&lt;/p&gt;

&lt;h3&gt;Takeaway Lessons&lt;/h3&gt;
&lt;p&gt;
Private browsing &amp;ldquo;mode&amp;rdquo; is no longer as modal as it used
to be.  Privacy-conscious users need to take a careful look at the
extensions they use&amp;mdash;especially ones that observe browser-wide
changes, like the session-manager example above&amp;mdash;and double-check
that they appear to behave properly with the new private-browsing
changes, or (better yet) have been updated to support PBM explicitly.
&lt;/p&gt;
&lt;p&gt;
Privacy-conscious developers need to take a careful look at their code
and ensure that it&apos;s robust enough to handle these changed semantics
for PBM, particularly in all code paths that occur
&lt;i&gt;after&lt;/i&gt; a check for PBM has returned &lt;i&gt;false&lt;/i&gt;.
&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The New MOOR's Law</title>
   <link href="http://blog.brownplt.org/2013/04/01/moor.html"/>
   <updated>2013-04-01T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2013/04/01/moor</id>
   <content type="html">&lt;div style=&quot;font-size: 10pt; font-family: arial&quot;&gt;

&lt;p&gt;&lt;em&gt;Though this was posted on April 1, and the quotes in this article should
be interpreted relative to that date, MOOR itself is not a joke.  Students from our
online course &lt;a href=&quot;https://blog.brownplt.org/2013/06/18/moocs-for-research.html&quot;&gt;produced a semantics for Python&lt;/a&gt;, with a &lt;a href=&quot;http://cs.brown.edu/research/plt/dl/lambda-py/&quot;&gt;paper describing it&lt;/a&gt; published at OOPSLA 2013.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PROVIDENCE, RI, USA&lt;/em&gt; - With the advent of Massively Open and Online
Courses (MOOCs), higher education faces a number of challenges.  Services like
Udacity and Coursera will provide learning services of equivalent quality for a
fraction of the cost, and may render the need for traditional education
institutions obsolete.  With the majority of universities receiving
much of their cash from undergraduate tuition, this makes the future of
academic &lt;em&gt;research&lt;/em&gt; uncertain as well.  &lt;/p&gt;

&lt;p style=&quot;width: 10em; float:right; font-size:12pt; padding: 1em; margin: 1em;
background-color: #eee; border: 1px solid black; text-align: left;&quot;&gt;&quot;[Brown]
lacks the endowment of a school like Harvard to weather the coming
storm.&quot;&lt;br/&gt;-Roberto Tamassia&lt;/br&gt;&lt;/p&gt;


&lt;p&gt;Schools may eventually adapt, but it&apos;s unclear what will happen to research
programs in the interim.  “I&apos;m concerned for the future of my department at
Brown University, which lacks the endowment of a school like Harvard to weather
the coming storm,” said Roberto Tamassia, chair of the Computer Science
department at Brown.&lt;/p&gt;

&lt;p&gt; But one Brown professor believes he has a solution for keeping his research
program alive through the impending collapse of higher education.  He calls it
MOOR: Massively Open and Online Research.  The professor, Shriram
Krishnamurthi, claims that MOOR can be researchers&apos; answer to MOOCs: “We&apos;ve
seen great user studies come out of crowdsourcing platforms like Mechanical
Turk.  MOOR will do the same for more technical research results; it&apos;s an
effective complement to Turk.”&lt;/p&gt;

&lt;p style=&quot;width: 10em; float:left; font-size:12pt; padding: 1em; margin: 1em;
background-color: #eee; border: 1px solid black; text-align: left;&quot;&gt;&quot;MOOR ... 
is an effective complement to [Mechanical] Turk.&quot;&lt;br/&gt;-Shriram Krishnamurthi&lt;/br&gt;&lt;/p&gt;

&lt;p&gt; MOOR will reportedly leverage the contributions of novice scholars from
around the globe in an integrated platform that aggregates experimental results
and proposed hypotheses.  This is combined with a unique algorithm that detects
and flags particularly insightful contributions.  This will allow research
results never before possible, says Joe Gibbs Politz: “I figure only one
in 10,000 people can figure out decidable and complete principal type inference
for a language with prototype-based inheritance and equirecursive subtyping.
So how could we even hope to solve this problem without 10,000 people working
on it?” &lt;/p&gt;

&lt;p&gt;Krishnamurthi has historically recruited undergraduate Brown students to aid
him in his research efforts.  Leo Meyerovich, a former Krishnamurthi acolyte,
is excited about changing the structure of the educational system, and shares
concerns about Krishnamurthi&apos;s research program.
With the number of undergraduates sure to dwindle to
nothing in the coming years, he says, “Shriram will need to come up with some new tricks.”&lt;/p&gt;

&lt;p&gt;Brown graduates Ed Lazowska and Peter Norvig appear to agree.  While
Lazowska refused to comment on behalf of the CRA, saying its position on the
matter is “still evolving,” speaking personally, he added, “evolve or die.”  As
of this writing, Peter Norvig has pledged a set of server farms and the 20%
time of 160,000 Google Engineers to support MOOR.  &lt;/p&gt;

&lt;p&gt; &lt;em&gt;With additional reporting from Kathi Fisler, Hannah Quay-de la Vallee,
Benjamin S. Lerner, and Justin Pombrio.&lt;/em&gt; &lt;/p&gt;

&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Essentials of Garbage Collection</title>
   <link href="http://blog.brownplt.org/2013/02/19/teaching-gc.html"/>
   <updated>2013-02-19T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2013/02/19/teaching-gc</id>
   <content type="html">&lt;style&gt;
  a:target {
    background-color: yellow;
  }
&lt;/style&gt;


&lt;p&gt;How do we teach students the essential ideas behind garbage
collection?&lt;/p&gt;

&lt;p&gt;A garbage collector (GC) implementation must address many
overlapping concerns. There are algorithmic decisions, e.g., the GC
algorithm to use; there are representation choices, e.g, the layout of
the stack; and there are assumptions about the language, e.g.,
unforgeable pointers. These choices, and more, affect each other
and make it very difficult for students to get off the ground.&lt;/p&gt;

&lt;p&gt;Programming language implementations can be similarly
complex. However, over the years, starting
from &lt;a href=&quot;#mccarthy:lisp&quot;&gt;McCarthy&apos;s seminal paper&lt;/a&gt;, we&apos;ve
found it invaluable to write &lt;i&gt;definitional interpreters&lt;/i&gt; for
simple core languages, that allow us to easily explore the
consequences of language design. What is the equivalent for garbage
collectors?&lt;/p&gt;

&lt;h3&gt;Testing and Curricular Dependencies&lt;/h3&gt;

&lt;p&gt;Testing is important for any program, and is doubly so for a
garbage collector, which must correctly deal with complex inputs
(i.e., programs!). Furthermore, correctness itself is subtle:
besides being efficient, a collector must terminate, be sound (not
collect non-garbage), be effective (actually collect enough true garbage),
and preserve the essential structure of live data: e.g., given a
cyclic datum, it must terminate, and given data with sharing, it must
preserve the sharing-structure and not duplicate data.&lt;/p&gt;

&lt;p&gt;For instructors, a further concern is the number of deep,
curricular dependencies that teaching GC normally incurs. In a course
where students already learn compilers and interpreters, it is
possible (but hard) to teach GC.  However, GC should be teachable in
several contexts, such as a systems course, an architecture course, or
even as a cool application of graph algorithms. Eliminating GC&apos;s
curricular dependencies is thus valuable.&lt;/p&gt;

&lt;p&gt;Even in courses that have student implement compilers or
interpreters, &lt;i&gt;testing&lt;/i&gt; a garbage collector is very hard. A 
test-case is a program that exercises the collector in an interesting
way.  Good tests require complex programs, and complex
programs require a rich programming language.  In courses,
students tend to write compilers and interpreters for simple, core
languages and are thus stuck writing correspondingly simple
programs. Worse, some important GC features, such as the treatment of
cycles and first-class functions, are impossible to test unless the
programming language being implemented
has the necessary features. Growing a core
language for the sake of testing GC would be a case of the tail
wagging the dog.&lt;/p&gt;

&lt;p&gt;In short, we would like a pedagogic framework where:

&lt;ul&gt;

  &lt;li&gt;Students can test their collectors using a full-blown
  programming language, instead of a stilted core language, and&lt;/li&gt;

  &lt;li&gt;Students can experiment with different GC algorithms and
  data-representations, without learning to implement
  languages.&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;The Key Idea&lt;/h3&gt;

&lt;p&gt;Over the past few years, we&apos;ve built a framework for teaching
garbage collection, first started by former Brown PhD
student &lt;a href=&quot;http://cs.brown.edu/~greg/&quot;&gt;Greg Cooper&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Consider the following Racket program, which would make a great
test-case for a garbage collector (with a suitably small heap):
&lt;pre&gt;
#lang racket

(define (map f l)
  (cond
   [(empty? l) empty]
   [(cons? l) (cons (f (first l))
                    (map f (rest l)))]))

(map (lambda (x) (+ x 1)) (list 1 2 3))
&lt;/pre&gt;
As written, Racket&apos;s native garbage collector allocates the closure
created by &lt;i&gt;lambda&lt;/i&gt; and the lists created by &lt;i&gt;cons&lt;/i&gt;
and &lt;i&gt;list&lt;/i&gt;.  But, what if we could route these calls to a
student-written collector and have it manage memory instead?&lt;/p&gt;

&lt;p&gt;Greg made the following simple observation. Why are these values being
managed by the Racket memory system? That&apos;s because the bindings for
&lt;i&gt;lambda&lt;/i&gt;, &lt;i&gt;cons&lt;/i&gt; and &lt;i&gt;list&lt;/i&gt; (and other procedures and
values) are provided by &lt;i&gt;#lang racket&lt;/i&gt;.  Instead, suppose that
with just one change, we could swap in a student-written collector:
&lt;pre&gt;
#lang plai/mutator
(allocator-setup &quot;my-mark-and-sweep.rkt&quot; 30)
&lt;/pre&gt;

Using the magic of Racket&apos;s modules and macros, &lt;i&gt;#lang
plai/mutator&lt;/i&gt; maps memory-allocating procedures to student-written
functions. The student designates a module, such
as &lt;i&gt;my-mark-and-sweep&lt;/i&gt; that exports a small, prescribed interface
for memory allocation. That module allocates values in a private heap
and runs its own GC algorithm when it runs out of space. In our
framework, the heap size is a parameter that is trivial to change. The
program above selects a heap size of 30, which is small enough to
trigger several GC cycles.&lt;/p&gt;


&lt;p&gt;We&apos;ve designed the framework so that students can easily swap in
different collectors, change the size of the heap, and even use
Racket&apos;s native collector, as a sanity check.&lt;/p&gt;

&lt;figure&gt;
&lt;img class=&quot;center&quot; src=&quot;/img/gc-framework.png&quot;&gt;
&lt;figcaption&gt;
  Our framework for writing garbage collectors.
&lt;/figcaption&gt;
&lt;/figure&gt;


&lt;h3&gt;Discovering GC Roots&lt;/h3&gt;

&lt;p&gt;Routing primitive procedures and constants is only half the
story. A collector also needs to inspect and modify the program stack,
which holds the roots of garbage collection.  Since we allow students
to write programs in Racket, the stack is just the Racket stack, which
is not open for reflection. Therefore, we must also transform
the program to expose the contents of the stack.&lt;/p&gt;

&lt;p&gt;Our framework automatically transforms Racket programs to
 &lt;a href=&quot;#flanagan:anf&quot;&gt;A-normal form&lt;/a&gt;, which names all
intermediate expressions in each activation record. Unlike other
transformations, say CPS, A-normalization preserves stack-layout. This
makes it easy for students to co-debug their programs and
collectors using the built-in DrRacket debugger.&lt;/p&gt;

&lt;p&gt;In addition to inspecting individual activation records, a
collector also needs to traverse the entire list of records on the
stack.  We maintain this list on the stack itself using
Racket&apos;s &lt;a href=&quot;#clements:cm&quot;&gt;continuation marks&lt;/a&gt;. Notably,
continuation marks preserve tail-calls, so the semantics of Racket
programs are unchanged.&lt;/p&gt;

&lt;p&gt;The combination of A-normalization and continuation marks gives us
a key technical advantage. In their absence, we would have to manually
convert programs to continuation-passing style (followed by
defunctionalization) to obtain roots. Not only would these be onerous
curricular dependencies, but they would make debugging very hard.&lt;/p&gt;

&lt;h3&gt;Controlling and Visualizing the Heap&lt;/h3&gt;

&lt;p&gt;Of course, we would like to prevent collectors from cheating. An
easy way to cheat is to simply allocate on the Racket heap.  We do not
go to great lengths to prevent all forms of cheating (these are
carefully-graded homeworks, after all). However, we do demand that
collectors access the &amp;ldquo;heap&amp;rdquo; 
through a low-level interface (where the
heap is actually just one large Racket array). This interface prevents
the storage of non-flat values, thereby forcing students to construct
compound representations for compound data. Notably, our framework is
flexible enough that we have students design their own memory
representations.&lt;/p&gt;

&lt;p&gt;The low-level heap interface has an added benefit. Because our
framework can tell &amp;ldquo;where the heap is&amp;rdquo;, and has access to the
student&apos;s heap-inspection procedures, we are able to provide a
fairly effective heap visualizer:


&lt;figure&gt;
&lt;img class=&quot;center&quot; src=&quot;/img/gc-heapviz.png&quot;&gt;
&lt;figcaption&gt;
  Visualizing the heap of a student-written semispace collector. The
visualizer dereferences pointers and draws arrows too!
&lt;/figcaption&gt;
&lt;/figure&gt;

Without this visualizer, students would have to print and examine
memory themselves. We agree that studying core dumps builds character,
but first-class debugging tools make for a gentler and more pleasant
learning experience. Due to this and other conveniences, our students
implement at least two distinct GC algorithms and extensive tests
within two weeks.&lt;/p&gt;

&lt;figure&gt;
&lt;img class=&quot;center&quot; src=&quot;/img/gc-hexfiend.png&quot;&gt;
&lt;figcaption&gt;
  HexFiend: Core dumps build character, but we don&apos;t inflict them on
  our students.
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h3&gt;Learn More&lt;/h3&gt;

&lt;p&gt;We&apos;ve been using this framework to teach garbage collection for
several years at several universities. It is now included with Racket,
too.  If you&apos;d like to play with the framework, check out
&lt;a href=&quot;http://faculty.cs.byu.edu/~jay/courses/2012/fall/330/course/gc.html&quot;&gt;one
of our GC homework assignments&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A &lt;a href=&quot;#cooper:gc&quot;&gt;pedagogic paper&lt;/a&gt; about this work will
appear at SIGCSE 2013.&lt;/p&gt;

&lt;h3&gt;References&lt;/h3&gt;

&lt;p&gt;&lt;a name=&quot;clements:cm&quot;&gt;[1] John Clements and Matthias Felleisen.  A
Tail-Recursive Machine with Stack Inspection. &lt;i&gt;ACM Transactions on
Programming Languages and Systems (TOPLAS), Vol. 26, No. 6, November
2004&lt;/i&gt;.&lt;/a&gt;
(&lt;a href=&quot;http://www.brinckerhoff.org/clements/papers/cf-toplas04.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;cooper:gc&quot;&gt;[2] Gregory H. Cooper, Arjun Guha, Shriram
Krishnamurthi, Jay McCarthy, and Robert Bruce Findler. Teaching
Garbage Collection without Implementing Compilers or
Interpreters. In &lt;i&gt;ACM Technical Symnposium on Computer Science
Education (SIGCSE) 2013&lt;/i&gt;.&lt;/a&gt;
(&lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Papers/Published/cgkmf-teach-gc/&quot;&gt;paper&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;flanagan:anf&quot;&gt;[3] Cormac Flanagan, Amr Sabry, Bruce
F. Duba, and Matthias Felleisen. The Essence of Compiling with
Continuations. In &lt;i&gt;ACM SIGPLAN Conference on Programming Language
Design and Implementation (PLDI), 1993&lt;/i&gt;.&lt;/a&gt;
(&lt;a href=&quot;http://users.soe.ucsc.edu/~cormac/papers/pldi93.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;mccarthy:lisp&quot;&gt;[4] John McCarthy. Recursive Functions of
Symbolic Expressions and their Computation by Machine, Part
1. &lt;i&gt;Communications of the ACM, Volume 3, Issue 4, April
1960.&lt;/i&gt;&lt;/a&gt;
(&lt;a href=&quot;http://www-formal.stanford.edu/jmc/recursive.html&quot;&gt;paper&lt;/a&gt;)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>(Sub)Typing First Class Field Names</title>
   <link href="http://blog.brownplt.org/2012/12/10/subtyping-first-class-field-names.html"/>
   <updated>2012-12-10T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2012/12/10/subtyping-first-class-field-names</id>
   <content type="html">&lt;p&gt;&lt;em&gt;This post picks up where a &lt;a href=&quot;https://blog.brownplt.org/2012/12/03/typing-first-class-field-names.html&quot;&gt;
previous post&lt;/a&gt; left off, and jumps back into the action with
subtyping.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;Updating Subtyping&lt;/h3&gt;

&lt;p&gt; There are two traditional rules for subtyping records, historically
known as &lt;em&gt;width&lt;/em&gt; and &lt;em&gt;depth&lt;/em&gt; subtyping.  Width subtyping
allows generalization by dropping fields; one record is a supertype of
another if it contains a subset of the sub-record&apos;s fields at the same
types.  Depth subtyping allows generalization within a field; one record
is a supertype of another if it is identical aside from generalizing one
field to a supertype of the type in the same field in the sub-record.
&lt;/p&gt;

&lt;p&gt;We would like to understand both of these kinds of subtyping in the
context of our first-class field names.  With traditional record types,
fields are either mentioned in the record or not.  Thus, for each
possible field in both types, there are four combinations to consider.
We can describe width and depth subtyping in a table:&lt;/p&gt;

&lt;style&gt;
table.subtyping {
  margin-left: 3em;
}
table.subtyping td {
  text-align: center;
  padding-left: 2em; 
  padding-right: 2em; 
}
table.subtyping th {
  text-align: center;
  padding-left: 2em; 
  padding-right: 2em; 
}
&lt;/style&gt;
&lt;table class=&quot;subtyping&quot;&gt;
&lt;tr&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;1&lt;/sub&gt;&lt;/code&gt;&lt;/th&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;2&lt;/sub&gt;&lt;/code&gt;&lt;/th&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;1&lt;/sub&gt; &amp;lt;: T&lt;sub&gt;2&lt;/sub&gt;&lt;/code&gt; if...&lt;/th&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;S &amp;lt;: T&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
  
&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Always&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Always&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;

&lt;p&gt;

We read &lt;code&gt;f: S&lt;/code&gt; as saying that &lt;code&gt;T&lt;sub&gt;1&lt;/sub&gt;&lt;/code&gt; has
the field &lt;code&gt;f&lt;/code&gt; with type &lt;code&gt;S&lt;/code&gt;, and we read &lt;code&gt;f:
-&lt;/code&gt; as saying that the corresponding type doesn&apos;t mention the field
&lt;code&gt;f&lt;/code&gt;.  The first row of the table corresponds to
&lt;em&gt;depth&lt;/em&gt; subtyping, where the field &lt;code&gt;f&lt;/code&gt; is still
present, but at a more general type in &lt;code&gt;T&lt;sub&gt;2&lt;/sub&gt;&lt;/code&gt;.  The
second row is a failure to subtype, when &lt;code&gt;T&lt;sub&gt;2&lt;/sub&gt;&lt;/code&gt; has
a field that isn&apos;t mentioned at all in &lt;code&gt;T&lt;sub&gt;1&lt;/sub&gt;&lt;/code&gt;. The
third row corresponds to &lt;em&gt;width&lt;/em&gt; subtyping, where a field is
dropped and not mentioned in the supertype.  The last row is a trivial
case, where neither type mentions the field.

&lt;/p&gt;

&lt;p&gt;

For records with string patterns, we can extend this table with new
combinations to account for ○ and ↓ annotations.  The old rows
remain, and become the ↓ cases, and new rows are added for ○
annotations:

&lt;/p&gt;

&lt;style&gt;
tr.newrow {
  background-color: #eee;
}
&lt;/style&gt;
&lt;table class=&quot;subtyping&quot;&gt;
&lt;tr&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;1&lt;/sub&gt;&lt;/code&gt;&lt;/th&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;2&lt;/sub&gt;&lt;/code&gt;&lt;/th&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;1&lt;/sub&gt; &amp;lt;: T&lt;sub&gt;2&lt;/sub&gt;&lt;/code&gt; if...&lt;/th&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;S &amp;lt;: T&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr class=&quot;newrow&quot;&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;
  
&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;

&lt;tr class=&quot;newrow&quot;&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;S &amp;lt;: T&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr class=&quot;newrow&quot;&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;S &amp;lt;: T&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr class=&quot;newrow&quot;&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;


&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Always&lt;/td&gt;
&lt;/tr&gt;

&lt;tr class=&quot;newrow&quot;&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Always&lt;/td&gt;
&lt;/tr&gt;


&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Always&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;

&lt;p&gt;

Here, we see that it is safe to treat a definitely present field as a
possibly-present one, in the case where we compare
&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;:S&lt;/code&gt; to &lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;:T&lt;/code&gt;).  The dual
of this case, treating a possibly-present field as definitely-present,
is unsafe, as the comparison of &lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;:S&lt;/code&gt; to
&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;:T&lt;/code&gt; shows.  Possibly present annotations do not
allow us to invent fields, as having &lt;code&gt;f: -&lt;/code&gt; on the
left-hand-side is still only permissible if the right-hand-side also
doesn&apos;t mention &lt;code&gt;f&lt;/code&gt;.


&lt;/p&gt;

&lt;h3&gt;Giving Types to Values&lt;/h3&gt;

&lt;p&gt;

In order to ascribe these rich types to object values, we need rules for
typing basic objects, and then we need to apply these subtyping rules to
generalize them.  As a working example, one place where objects with
field patterns come up every day in practice is in JavaScript arrays.
Arrays in JavaScript hold their elements in fields named by stringified
numbers.  Thus, a simplified type for a JavaScript array of booleans is
roughly:

&lt;/p&gt;

&lt;pre&gt;
BoolArrayFull: { [0-9]+&lt;sup&gt;○&lt;/sup&gt;: Bool }
&lt;/pre&gt;

&lt;p&gt; That is, each field made up of a sequence of digits is possibly
present, and if it is there, it has a boolean value.  For simplicity,
let&apos;s consider a slightly neutered version of this type, where only
single digit fields are allowed: &lt;/p&gt;

&lt;pre&gt;
BoolArray: { [0-9]&lt;sup&gt;○&lt;/sup&gt;: Bool }
&lt;/pre&gt;

&lt;p&gt;Let&apos;s think about how we&apos;d go about typing a value that should
clearly have this type: the array &lt;code&gt;[true, false]&lt;/code&gt;.  We can
think of this array literal as desugaring into an object like (indeed,
this is what &lt;a href=&quot;https://blog.brownplt.org/2011/09/29/js-essence.html&quot;&gt;λJS&lt;/a&gt;
does):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We would like to be able to state that this object is a member of the
&lt;code&gt;BoolArray&lt;/code&gt; type above.  The traditional rule for record
typing would ascribe a type mapping the names that are present to the
types of their right hand side.  Since the fields are certainly present,
in our notation we can write:&lt;/p&gt;

&lt;pre&gt;
{&quot;0&quot;&lt;sup&gt;↓&lt;/sup&gt;: Bool, &quot;1&quot;&lt;sup&gt;↓&lt;/sup&gt;: Bool}
&lt;/pre&gt;

&lt;p&gt;This type should certainly be generalizable to
&lt;code&gt;BoolArray&lt;/code&gt;.  That is, it should hold (using the rules in the
table above) that:&lt;/p&gt;

&lt;pre&gt;
{&quot;0&quot;&lt;sup&gt;↓&lt;/sup&gt;: Bool, &quot;1&quot;&lt;sup&gt;↓&lt;/sup&gt;: Bool} &amp;lt;: { [0-9]&lt;sup&gt;○&lt;/sup&gt;: Bool }
&lt;/pre&gt;

&lt;p&gt;Let&apos;s see what happens when we instantiate the table for these two
types:&lt;/p&gt;

&lt;style&gt;
td.subtyping-fail {
  color: #cc0001;
  font-weight: bold;
}
td.subtyping-pass {
  color: #1f8011;
  font-weight: bold;
}
&lt;/style&gt;
&lt;table class=&quot;subtyping&quot;&gt;
&lt;tr&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;1&lt;/sub&gt;&lt;/code&gt;&lt;/th&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;2&lt;/sub&gt;&lt;/code&gt;&lt;/th&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;1&lt;/sub&gt; &amp;lt;: T&lt;sub&gt;2&lt;/sub&gt;&lt;/code&gt; if...&lt;/th&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;0&lt;sup&gt;↓&lt;/sup&gt;: Bool&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;0&lt;sup&gt;○&lt;/sup&gt;: Bool&lt;/code&gt;&lt;/td&gt;
  &lt;td class=&apos;subtyping-pass&apos;&gt;&lt;code&gt;Bool &amp;lt;: Bool&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;1&lt;sup&gt;↓&lt;/sup&gt;: Bool&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;1&lt;sup&gt;○&lt;/sup&gt;: Bool&lt;/code&gt;&lt;/td&gt;
  &lt;td class=&apos;subtyping-pass&apos;&gt;&lt;code&gt;Bool &amp;lt;: Bool&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;3: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;3&lt;sup&gt;○&lt;/sup&gt;: Bool&lt;/code&gt;&lt;/td&gt;
  &lt;td class=&apos;subtyping-fail&apos;&gt;Fail!&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;4: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;4&lt;sup&gt;○&lt;/sup&gt;: Bool&lt;/code&gt;&lt;/td&gt;
  &lt;td class=&apos;subtyping-fail&apos;&gt;Fail!&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt; ... &lt;/td&gt;
  &lt;td&gt; ... &lt;/td&gt;
  &lt;td&gt; ... &lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;

&lt;p&gt;

(We cut off the table for 5-9, which are the same as the cases for 3 and
4).  Our subtyping fails to hold for these types, which don&apos;t let us
reflect the fact that the fields 3 and 4 are actually absent, and we
should be allowed to consider them as possibly present at the boolean
type.  In fact, our straightforward rule for typing records is in fact
responsible for throwing away this information!  The type that it
ascribed,

&lt;/p&gt;

&lt;pre&gt;
{&quot;0&quot;&lt;sup&gt;↓&lt;/sup&gt;: Bool, &quot;1&quot;&lt;sup&gt;↓&lt;/sup&gt;: Bool}
&lt;/pre&gt;

&lt;p&gt;

is actually the type of many objects, including those that happen to
have fields like &lt;code&gt;&quot;banana&quot; : 42&lt;/code&gt;.  Traditional record typing
drops fields when it doesn&apos;t care if they are present or absent, which
loses information about definitive absence.

&lt;/p&gt;

&lt;p&gt;

We extend our type language once more to keep track of this information.
We add an explicit piece of a record type that tracks a description of
the fields that are &lt;em&gt;definitely absent&lt;/em&gt; on an object, and use
this for typing object literals:

&lt;/p&gt;

&lt;pre&gt;
p = ○ | ↓
T = ... | { L&lt;sup&gt;p&lt;/sup&gt; : T ..., L&lt;sub&gt;A&lt;/sub&gt;: &lt;b&gt;abs&lt;/b&gt; }
&lt;/pre&gt;

&lt;p&gt;

Thus, the new type for &lt;code&gt;[&quot;0&quot;: true, &quot;1&quot;: false]&lt;/code&gt; would be:

&lt;/p&gt;

&lt;style&gt;
.complement {
  border-top: 1px solid black;
}
&lt;/style&gt;
&lt;pre&gt;
{&quot;0&quot;&lt;sup&gt;↓&lt;/sup&gt;: Bool, &quot;1&quot;&lt;sup&gt;↓&lt;/sup&gt;: Bool, &lt;span class=&quot;complement&quot;&gt;(&quot;0&quot;|&quot;1&quot;)&lt;/span&gt;: &lt;b&gt;abs&lt;/b&gt;}
&lt;/pre&gt;

&lt;p&gt;

Here, the &lt;span class=&apos;complement&apos;&gt;overbar&lt;/span&gt; denotes
regular-expression complement, and this type is expressing that all
fields other than &lt;code&gt;&quot;0&quot;&lt;/code&gt; and &lt;code&gt;&quot;1&quot;&lt;/code&gt; are definitely
absent.

&lt;/p&gt;

&lt;p&gt;Adding another type of field annotation requires that we again extend
our table of subtyping options, so we now have a complete description
with 16 cases:&lt;/p&gt;


&lt;table class=&quot;subtyping&quot;&gt;
&lt;tr&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;1&lt;/sub&gt;&lt;/code&gt;&lt;/th&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;2&lt;/sub&gt;&lt;/code&gt;&lt;/th&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;1&lt;/sub&gt; &amp;lt;: T&lt;sub&gt;2&lt;/sub&gt;&lt;/code&gt; if...&lt;/th&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;S &amp;lt;: T&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;
  
&lt;tr class=&apos;newrow&apos;&gt;
  &lt;td&gt;&lt;code&gt;f: &lt;b&gt;abs&lt;/b&gt;&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;S &amp;lt;: T&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;S &amp;lt;: T&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr class=&apos;newrow&apos;&gt;
  &lt;td&gt;&lt;code&gt;f: &lt;b&gt;abs&lt;/b&gt;&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Always&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: T&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;

&lt;tr class=&apos;newrow&apos;&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: &lt;b&gt;abs&lt;/b&gt;&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;

&lt;tr class=&apos;newrow&apos;&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: &lt;b&gt;abs&lt;/b&gt;&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;

&lt;tr class=&apos;newrow&apos;&gt;
  &lt;td&gt;&lt;code&gt;f: &lt;b&gt;abs&lt;/b&gt;&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: &lt;b&gt;abs&lt;/b&gt;&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Always&lt;/td&gt;
&lt;/tr&gt;

&lt;tr class=&apos;newrow&apos;&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: &lt;b&gt;abs&lt;/b&gt;&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Always&lt;/td&gt;
&lt;/tr&gt;


&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: S&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Always&lt;/td&gt;
&lt;/tr&gt;

&lt;tr class=&apos;newrow&apos;&gt;
  &lt;td&gt;&lt;code&gt;f: &lt;b&gt;abs&lt;/b&gt;&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Always&lt;/td&gt;
&lt;/tr&gt;


&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;f: -&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;Always&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;

&lt;p&gt;
We see that absent fields cannot be generalized to be definitely present
(the &lt;code&gt;&lt;b&gt;abs&lt;/b&gt;&lt;/code&gt; to &lt;code&gt;f&lt;sup&gt;↓&lt;/sup&gt;&lt;/code&gt; case), but
they &lt;em&gt;can&lt;/em&gt; be generalized to be possibly present at any type.
This is expressed in the case that compares &lt;code&gt;f : &lt;b&gt;abs&lt;/b&gt;&lt;/code&gt;
to &lt;code&gt;f&lt;sup&gt;○&lt;/sup&gt;: T&lt;/code&gt;, which always holds for any
&lt;code&gt;T&lt;/code&gt;.  To see these rules in action, we can instantiate them
for the array example we&apos;ve been working with to ask a new question:

&lt;/p&gt;

&lt;pre&gt;
{&quot;0&quot;&lt;sup&gt;↓&lt;/sup&gt;: Bool, &quot;1&quot;&lt;sup&gt;↓&lt;/sup&gt;: Bool, &lt;span class=&quot;complement&quot;&gt;(&quot;0&quot;|&quot;1&quot;)&lt;/span&gt;: &lt;b&gt;abs&lt;/b&gt;} &amp;lt;: { [0-9]&lt;sup&gt;○&lt;/sup&gt;: Bool }
&lt;/pre&gt;

&lt;p&gt;And the table:&lt;/p&gt;

&lt;table class=&quot;subtyping&quot;&gt;
&lt;tr&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;1&lt;/sub&gt;&lt;/code&gt;&lt;/th&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;2&lt;/sub&gt;&lt;/code&gt;&lt;/th&gt;
  &lt;th&gt;&lt;code&gt;T&lt;sub&gt;1&lt;/sub&gt; &amp;lt;: T&lt;sub&gt;2&lt;/sub&gt;&lt;/code&gt; if...&lt;/th&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;0&lt;sup&gt;↓&lt;/sup&gt;: Bool&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;0&lt;sup&gt;○&lt;/sup&gt;: Bool&lt;/code&gt;&lt;/td&gt;
  &lt;td class=&apos;subtyping-pass&apos;&gt;&lt;code&gt;Bool &amp;lt;: Bool&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;1&lt;sup&gt;↓&lt;/sup&gt;: Bool&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;1&lt;sup&gt;○&lt;/sup&gt;: Bool&lt;/code&gt;&lt;/td&gt;
  &lt;td class=&apos;subtyping-pass&apos;&gt;&lt;code&gt;Bool &amp;lt;: Bool&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;3: &lt;b&gt;abs&lt;/b&gt;&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;3&lt;sup&gt;○&lt;/sup&gt;: Bool&lt;/code&gt;&lt;/td&gt;
  &lt;td class=&apos;subtyping-pass&apos;&gt;OK!&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;4: &lt;b&gt;abs&lt;/b&gt;&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;4&lt;sup&gt;○&lt;/sup&gt;: Bool&lt;/code&gt;&lt;/td&gt;
  &lt;td class=&apos;subtyping-pass&apos;&gt;OK!&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt; ... &lt;/td&gt;
  &lt;td&gt; ... &lt;/td&gt;
  &lt;td&gt; ... &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;9: &lt;b&gt;abs&lt;/b&gt;&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;9&lt;sup&gt;○&lt;/sup&gt;: Bool&lt;/code&gt;&lt;/td&gt;
  &lt;td class=&apos;subtyping-pass&apos;&gt;OK!&lt;/td&gt;
&lt;/tr&gt;


&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;foo: &lt;b&gt;abs&lt;/b&gt;&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;foo: -&lt;/code&gt;&lt;/td&gt;
  &lt;td class=&apos;subtyping-pass&apos;&gt;OK!&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;bar: &lt;b&gt;abs&lt;/b&gt;&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code&gt;bar: -&lt;/code&gt;&lt;/td&gt;
  &lt;td class=&apos;subtyping-pass&apos;&gt;OK!&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
  &lt;td&gt; ... &lt;/td&gt;
  &lt;td&gt; ... &lt;/td&gt;
  &lt;td&gt; ... &lt;/td&gt;
&lt;/tr&gt;



&lt;/table&gt;

&lt;p&gt;

There&apos;s two things that make this possible.  First, it is sound to
generalize the absent fields that are possibly present on the array
type, because the larger type doesn&apos;t guarantee their presence either.
Second, it is sound to generalize absent fields that aren&apos;t mentioned on
the array type, because unmentioned fields can be present or absent with
any type.  The combination of these two features of our subtyping
relation lets us generalize from particular array instances to the more
general type for arrays.

&lt;/p&gt;

&lt;h3&gt;Capturing the Whole Table&lt;/h3&gt;

&lt;p&gt;

The tables above present subtyping on a field-by-field basis, and the
patterns we considered at first were finite.  In the last case, however,
the pattern of “fields other than 0 and 1” was in fact infinite, and we
cannot actually construct that infinite table to describe subtyping.
The &lt;a href=&quot;http://www.cs.brown.edu/research/plt/dl/fcfn/v1/&quot;&gt;writeup
and its associated proof document&lt;/a&gt; lay out an algorithmic version of
the rules presented in the tables above, and also provides a proof of
their soundness.

&lt;/p&gt;

&lt;p&gt;

The writeup also discusses another interesting problem, which is the
interaction between these pattern types and inheritance, where patterns
on the child and parent objects may overlap in subtle ways.  It goes
further and discusses what happens in cases like JavaScript, where the
field &lt;code&gt;&quot;__proto__&quot;&lt;/code&gt; is an accessible member that has
inheritance semantics.  Check it all out &lt;a
href=&quot;http://www.cs.brown.edu/research/plt/dl/fcfn/v1/&quot;&gt;here&lt;/a&gt;!

&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Typing First Class Field Names</title>
   <link href="http://blog.brownplt.org/2012/12/03/typing-first-class-field-names.html"/>
   <updated>2012-12-03T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2012/12/03/typing-first-class-field-names</id>
   <content type="html">&lt;p&gt;In a &lt;a href=&quot;https://blog.brownplt.org/2012/02/28/scripting-objects.html&quot;&gt;previous post&lt;/a&gt;,
we discussed some of the powerful features of objects in scripting
languages.  One feature that stood out was the use of first-class
strings as member names for objects.  That is, in programs like&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Bob&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; the name position in field lookup has been abstracted over.
Presumably only a finite set of names actually works with the lookup
(&lt;code&gt;o&lt;/code&gt; appears to only have two fields, after all).&lt;/p&gt;

&lt;p&gt; It turns out that so-called “scripting” languages aren&apos;t the only
ones that compute fields for lookup.  For example, even within the
constraints of Java&apos;s type system, the Bean framework computes method
names to call at runtime.  Developers can provide information about the
names of fields and methods on a Bean with a &lt;a
href=&quot;http://docs.oracle.com/javase/7/docs/api/java/beans/BeanInfo.html&quot;&gt;&lt;code&gt;BeanInfo&lt;/code&gt;&lt;/a&gt;
instance, but even if they don&apos;t provide complete information, “the rest
will be obtained by automatic analysis using low-level reflection of the
bean classes’ methods and applying standard design patterns.”  These
“standard design patterns” include, for example, concatenating the
strings &lt;code&gt;&quot;get&quot;&lt;/code&gt; and &lt;code&gt;&quot;set&quot;&lt;/code&gt; onto field names to
produce method names to invoke at runtime.&lt;/p&gt;

&lt;p&gt;Traditional type systems for objects and records have little to say
about these computed accesses.  In this post, we&apos;re going to build up a
description of object types that can describe these values, and explore
their use.  The ideas in this post are developed more fully in a &lt;a
href=&quot;http://www.cs.brown.edu/research/plt/dl/fcfn/v1/&quot;&gt;writeup
for the FOOL Workshop&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;First-class Singleton Strings&lt;/h3&gt;

&lt;p&gt;
In the JavaScript example above, we said that it&apos;s likely that the only
intended lookup targets―and thus the only intended arguments to
&lt;code&gt;lookup&lt;/code&gt;―are &lt;code&gt;&quot;name&quot;&lt;/code&gt; and &lt;code&gt;&quot;age&quot;&lt;/code&gt;.
Giving a meaningful type to this function is easy if we allow singleton
strings as types in their own right.  That is, if our type language is:
&lt;/p&gt;

&lt;pre&gt;
T = s | Str | Num
  | { s : T ... } | T → T | T ∩ T
&lt;/pre&gt;

&lt;p&gt;

Where &lt;code&gt;s&lt;/code&gt; stands for any singleton string, &lt;code&gt;Str&lt;/code&gt;
and &lt;code&gt;Num&lt;/code&gt; are base types for strings and numbers,
respectively, record types are a map from singleton strings
&lt;code&gt;s&lt;/code&gt; to types, arrow types are traditional pairs of types, and
intersections are allowed to express a conjunction of types on the same
value.

&lt;/p&gt;

&lt;p&gt;
Given these definitions, we could write the type of lookup as:
&lt;/p&gt;

&lt;pre&gt;
lookup : (&quot;name&quot; → Str) ∩ (&quot;age&quot; → Num)
&lt;/pre&gt;

&lt;p&gt;That is, if &lt;code&gt;lookup&lt;/code&gt; is provided the string
&lt;code&gt;&quot;name&quot;&lt;/code&gt;, it produces a string, and if it is provided the
string &lt;code&gt;&quot;age&quot;&lt;/code&gt;, it produces a number.
&lt;/p&gt;

&lt;p&gt;In order to type-check the body of &lt;code&gt;lookup&lt;/code&gt;, we need a
type for &lt;code&gt;o&lt;/code&gt; as well.  That can be represented with the type
&lt;code&gt;{ &quot;name&quot; : Str, &quot;age&quot; : Num }&lt;/code&gt;.  Finally, to type-check the
object lookup expression &lt;code&gt;o[f]&lt;/code&gt;, we need to compare the
singleton string type of &lt;code&gt;f&lt;/code&gt; with the fields of
&lt;code&gt;o&lt;/code&gt;.  In this case, only the two strings that are already
present on &lt;code&gt;o&lt;/code&gt; are possible choices for &lt;code&gt;f&lt;/code&gt;, so
the comparison is easy and type-checking works out.
&lt;/p&gt;

&lt;p&gt;For a first cut, all we did was make the string labels on objects&apos;
fields a first-class entity in our type system, with singleton string
types &lt;code&gt;s&lt;/code&gt;.  But what can we say about the Bean example, where
&lt;code&gt;get*&lt;/code&gt; and &lt;code&gt;set*&lt;/code&gt; method invocations are computed
rather than just used as first-class values?&lt;/p&gt;

&lt;h3&gt;String Pattern Types&lt;/h3&gt;

&lt;p&gt;
In order to express the type of objects like Beans, we need to express
field name &lt;em&gt;patterns&lt;/em&gt;, rather than just singleton field names.
For example, we might say that a Bean with &lt;code&gt;Int&lt;/code&gt;-typed
parameters has a type like:
&lt;/p&gt;

&lt;pre&gt;
IntBean = { (&quot;get&quot;.+)  : → Int },
            (&quot;set&quot;.+)  : Int → Void,
            &quot;toString&quot; : → Str }
&lt;/pre&gt;

&lt;p&gt; Here, we are using &lt;code&gt;.+&lt;/code&gt; as regular expression notation
for any non-empty string.  We read the type above as saying that all
fields that begin with &lt;code&gt;get&lt;/code&gt; and end with any string are
functions that return &lt;code&gt;Int&lt;/code&gt; values.  The same is true for
&lt;code&gt;&quot;set&quot;&lt;/code&gt; methods.  The singleton string &lt;code&gt;&quot;toString&quot;&lt;/code&gt;
is also a field, and is simply a function that returns strings.  &lt;/p&gt;

&lt;p&gt;
To express this type, we need to extend our type language to handle
these string &lt;em&gt;patterns&lt;/em&gt;, which we write down as regular
expressions (the write-up outlines the actual limits on what kinds of
patterns we can support).  We extend our type language to include
patterns as types, and as field names:
&lt;/p&gt;

&lt;pre&gt;
L = &lt;em&gt;regular expressions&lt;/em&gt;
T = L | Str | Num
  | { L : T ... } | T → T | T ∩ T
&lt;/pre&gt;

&lt;p&gt;

This new specification gives us the ability to write down types like
&lt;code&gt;IntBean&lt;/code&gt;, which have field patterns that describe
&lt;em&gt;infinite&lt;/em&gt; sets of fields.  Let&apos;s stop and think about what that
means as a description of a runtime object.  Our type for &lt;code&gt;o&lt;/code&gt;
above, &lt;code&gt;{ &quot;name&quot; : Str, &quot;age&quot; : Num }&lt;/code&gt;, says that values
bound to &lt;code&gt;o&lt;/code&gt; at runtime certainly have &lt;code&gt;name&lt;/code&gt; and
&lt;code&gt;age&lt;/code&gt; fields at the listed types.  The type for
&lt;code&gt;IntBean&lt;/code&gt;, on the other hand, seems to assert that these
objects will have the fields &lt;code&gt;getUp&lt;/code&gt;, &lt;code&gt;getDown&lt;/code&gt;,
&lt;code&gt;getSerious&lt;/code&gt;, and infinitely more.  But a runtime object
can&apos;t &lt;em&gt;actually&lt;/em&gt; have all of those fields, so a pattern
indicating an infinite number of field names is describing a
fundamentally different kind of value.

&lt;/p&gt;

&lt;p&gt;

What an object type with an infinite pattern represents is that all the
fields that match the pattern are &lt;em&gt;potentially&lt;/em&gt; present.  That
is, at runtime, they may or may not be there, but if they are there,
they must have the annotated type.  We extend object types again to make
this explicit with &lt;em&gt;presence&lt;/em&gt; annotations, which explicitly list
fields as &lt;em&gt;definitely present&lt;/em&gt;, written ↓, or &lt;em&gt;possibly
present&lt;/em&gt;, written ○:

&lt;/p&gt;

&lt;pre&gt;
p = ○ | ↓
T = ... | { L&lt;sup&gt;p&lt;/sup&gt; : T ... }
&lt;/pre&gt;

&lt;p&gt; In this notation, we would write: &lt;/p&gt;

&lt;pre&gt;
IntBean = { (&quot;get&quot;.+)&lt;sup&gt;○&lt;/sup&gt;  : → Int },
            (&quot;set&quot;.+)&lt;sup&gt;○&lt;/sup&gt;  : Int → Void,
            &quot;toString&quot;&lt;sup&gt;↓&lt;/sup&gt; : → Str }
&lt;/pre&gt;

&lt;p&gt;Which indicates that all the fields in &lt;code&gt;(&quot;get&quot;.+)&lt;/code&gt; and
&lt;code&gt;(&quot;set&quot;.+)&lt;/code&gt; are &lt;em&gt;possibly present&lt;/em&gt; with the given
arrow types, and &lt;code&gt;toString&lt;/code&gt; is &lt;em&gt;definitely present&lt;/em&gt;.
&lt;/p&gt;

&lt;h3&gt;Subtyping&lt;/h3&gt;

&lt;p&gt;Now that we have these rich object types, it&apos;s natural to ask what
kinds of subtyping relationships they have with one another.  A detailed
account of subtyping will come soon; in the meantime, can you guess what
subtyping might look like for these types?&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; The answer is in the &lt;a href=&quot;https://blog.brownplt.org/2012/12/10/subtyping-first-class-field-names.html&quot;&gt;
next post&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>S5: Engineering Eval</title>
   <link href="http://blog.brownplt.org/2012/10/21/js-eval.html"/>
   <updated>2012-10-21T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2012/10/21/js-eval</id>
   <content type="html">&lt;style&gt;
.quiz-explanation {
  display: none;
}

.response {
  padding-top: 15pt;
  text-align: center;
  font-family: Helvetica, Arial, sans-serif;
}


.nope {
  color: #cc0001;
}

.yep {
  color: #3f31a0;
}

.quiz-question {
  width: 100%;
  border-top: 1px dashed gray;
}

.quiz-holder {
  width: 40%;
  float: left;
}

.quiz {
  padding-left: 40pt;
}

.quiz p {
  font-family: Helvetica, Arial, sans-serif;
  line-height: 1;
}

.quiz button.selected {
  background-color: #5f51c0;
  border: 2px solid #1f1180;
}

.quiz button.selected:hover {
  background-color: #5f51c0;
  border: 2px solid #1f1180;
}

.quiz button {
  min-width: 30%;
  height: 20pt;
  background-color: #1f1180;
  color: white;
  border: none;
  border-radius: 5pt;
  border: 2px solid white;
}

.quiz button:hover {
  cursor: pointer;
  background-color: #3f31a0;
  border: 2px solid white;
}

.redhead {
  padding: 5pt;
  color: white;
  background-color: #cc0001;
  font-weight: bold;
}

.bluehead {
  padding: 5pt;
  color: white;
  background-color: #1f1180;
  font-weight: bold;
}

.redrow {
  background-color: #fcc0c1;
}

.bluerow {
  background-color: #afc1f0;
}

.boldrow {
  font-weight: bold;
}

.redrow td {
  padding: 3pt;
}
.bluerow td {
  padding: 3pt;
}
&lt;/style&gt;


&lt;p&gt;In an &lt;a href=&quot;https://blog.brownplt.org/2011/11/11/s5-javascript-semantics.html&quot;&gt;earlier post&lt;/a&gt;, we
introduced S5, our semantics for ECMAScript 5.1 (ES5).  S5 is no toy,
but strives to correctly model JavaScript&apos;s messy details.&lt;/p&gt;

&lt;p&gt;One such messy detail of JavaScript is &lt;code&gt;eval&lt;/code&gt;.  The
behavior of &lt;code&gt;eval&lt;/code&gt; was updated in the ES5 specification to
make its behavior less surprising and give more control to programmers.
However, the old behavior was left intact for backwards compatibility.
This has led to a language construct with a number of subtle behaviors.
Today, we&apos;re going to explore JavaScript&apos;s &lt;code&gt;eval&lt;/code&gt;, explain
its several modes, and describe our approach to engineering an
implementation of it.  &lt;/p&gt;

&lt;h3&gt;Quiz Time!&lt;/h3&gt;

&lt;p&gt;We&apos;ve put together a short quiz to give you a tour of the various
types of &lt;code&gt;eval&lt;/code&gt; in JavaScript.  How many can you get right on
the first try?&lt;/p&gt;

&lt;noscript&gt;
&lt;p&gt;&lt;i&gt;The interactive quiz requires that you have JavaScript enabled.  You
can still see the programs we ask about below, but the experience is a
lot more fun if you can click the buttons and get feedback on your
answers.&lt;/i&gt;&lt;/p&gt;
&lt;/noscript&gt;

&lt;div class=&quot;quiz-question&quot;&gt;
  &lt;p&gt;Question 1&lt;/p&gt;
  &lt;div style=&quot;width:55%; float:left;&quot;&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;var x = 2;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  &lt;/div&gt;

  &lt;div class=&quot;quiz-holder&quot;
       data-answers=&apos;[&quot;1&quot;,&quot;2&quot;,&quot;Other&quot;]&apos;
       data-correct=&apos;2&apos;
       data-label=&apos;What does f(1) return?&apos;&gt;
  &lt;/div&gt;

  &lt;div class=&apos;clear&apos;&gt;&lt;/div&gt;

  &lt;p class=&quot;quiz-explanation&quot;&gt;
    &lt;code&gt;f(1) === 2&lt;/code&gt;&lt;br/&gt;
    This example returns 2 because the &lt;code&gt;var&lt;/code&gt; declaration in
the &lt;code&gt;eval&lt;/code&gt; actually refers to the &lt;em&gt;same&lt;/em&gt; variables as
the body of the function.  So, the &lt;code&gt;eval&lt;/code&gt; body overwrites the
&lt;code&gt;x&lt;/code&gt; parameter and returns the new value.
  &lt;/p&gt;

&lt;/div&gt;

&lt;div class=&quot;quiz-question&quot;&gt;
  &lt;p&gt;Question 2&lt;/p&gt;
  &lt;div style=&quot;width:55%; float:left;&quot;&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&apos;use strict&apos;; var x = 2;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  &lt;/div&gt;

  &lt;div class=&quot;quiz-holder&quot;
       data-answers=&apos;[&quot;1&quot;,&quot;2&quot;,&quot;Other&quot;]&apos;
       data-correct=&apos;1&apos;
       data-label=&apos;What does f(1) return?&apos;&gt;
  &lt;/div&gt;

  &lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;

  &lt;p class=&quot;quiz-explanation&quot;&gt;
    &lt;code&gt;f(1) === 1&lt;/code&gt;&lt;br/&gt;
    The &lt;code&gt;&apos;use strict&apos;;&lt;/code&gt; directive creates a new scope for
    variables defined inside the &lt;code&gt;eval&lt;/code&gt;.  So, the
    &lt;code&gt;var x = 2;&lt;/code&gt; still evaluates, but doesn&apos;t affect the
    &lt;code&gt;x&lt;/code&gt; that is the function&apos;s parameter.  These first two
    examples show that &lt;em&gt;strict mode&lt;/em&gt;
    changes the scope that &lt;code&gt;eval&lt;/code&gt; &lt;em&gt;affects&lt;/em&gt;.  We might
ask, now that we&apos;ve seen these, what scope does &lt;code&gt;eval&lt;/code&gt;
&lt;em&gt;see&lt;/em&gt;?
  &lt;/p&gt;

&lt;/div&gt;

&lt;div class=&quot;quiz-question&quot;&gt;
  &lt;p&gt;Question 3&lt;/p&gt;
  &lt;div style=&quot;width:55%; float:left;&quot;&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;var x = y;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  &lt;/div&gt;

  &lt;div class=&quot;quiz-holder&quot;
       data-answers=&apos;[&quot;1&quot;,&quot;2&quot;,&quot;Other&quot;]&apos;
       data-correct=&apos;Other&apos;
       data-label=&apos;What does f(1) return?&apos;&gt;
  &lt;/div&gt;

&lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;

  &lt;p class=&quot;quiz-explanation&quot;&gt;
    &lt;code&gt;f(1) === &lt;span style=&quot;color: red&quot;&gt;ReferenceError: y is not defined&lt;/span&gt;&lt;/code&gt;&lt;br/&gt;
    OK, that was sort of a trick question.  This program throws an
exception saying that &lt;code&gt;y&lt;/code&gt; is unbound.  But it serves to
remind us of an important JavaScript feature; if a variable isn&apos;t
defined in a scope, trying to access it is an exception.  Now we can ask
the obvious question: can we see &lt;code&gt;y&lt;/code&gt; if we define it outside
the &lt;code&gt;eval&lt;/code&gt;?
  &lt;/p&gt;
&lt;/div&gt;


&lt;div class=&quot;quiz-question&quot;&gt;
  &lt;p&gt;Question 4&lt;/p&gt;
  &lt;div style=&quot;width:55%; float:left;&quot;&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;var x = y;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  &lt;/div&gt;

  &lt;div class=&quot;quiz-holder&quot;
       data-answers=&apos;[&quot;1&quot;,&quot;2&quot;,&quot;Other&quot;]&apos;
       data-correct=&apos;2&apos;
       data-label=&apos;What does f(1) return?&apos;&gt;
  &lt;/div&gt;

&lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;

  &lt;p class=&quot;quiz-explanation&quot;&gt;
  &lt;code&gt;f(1) === 2&lt;/code&gt;&lt;br/&gt;
    OK, here&apos;s our real answer.  The &lt;code&gt;y&lt;/code&gt; is certainly visible
inside the &lt;code&gt;eval&lt;/code&gt;, which can both see and affect the outer
scope.  What if the &lt;code&gt;eval&lt;/code&gt; is strict?
  &lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;quiz-question&quot;&gt;
  &lt;p&gt;Question 5&lt;/p&gt;
  &lt;div style=&quot;width:55%; float:left;&quot;&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&apos;use strict&apos;; var x = y;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  &lt;/div&gt;

  &lt;div class=&quot;quiz-holder&quot;
       data-answers=&apos;[&quot;1&quot;,&quot;2&quot;,&quot;Other&quot;]&apos;
       data-correct=&apos;1&apos;
       data-label=&apos;What does f(1) return?&apos;&gt;
  &lt;/div&gt;

  &lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;

  &lt;p class=&quot;quiz-explanation&quot;&gt;
  &lt;code&gt;f(1) === 1&lt;/code&gt;&lt;br/&gt;
    Interestingly, we &lt;em&gt;don&apos;t&lt;/em&gt; get an error here, so
    it seems like &lt;code&gt;y&lt;/code&gt; was visible to the &lt;code&gt;eval&lt;/code&gt;
    even in strict mode.  However, as before the assignment doesn&apos;t
    escape.  New topic next.
  &lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;quiz-question&quot;&gt;
  &lt;p&gt;Question 6&lt;/p&gt;
  &lt;div style=&quot;width:55%; float:left;&quot;&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;avel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;avel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;var x = y;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  &lt;/div&gt;

  &lt;div class=&quot;quiz-holder&quot;
       data-answers=&apos;[&quot;1&quot;,&quot;2&quot;,&quot;Other&quot;]&apos;
       data-correct=&apos;Other&apos;
       data-label=&apos;What does f(1) return?&apos;&gt;
  &lt;/div&gt;

  &lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;

  &lt;p class=&quot;quiz-explanation&quot;&gt;
    &lt;code&gt;f(1) === &lt;span style=&quot;color: red&quot;&gt;ReferenceError: y is not defined&lt;/span&gt;&lt;/code&gt;&lt;br/&gt;
    OK, that was a gimme.  Lets add the variable declaration we need.
  &lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;quiz-question&quot;&gt;
  &lt;p&gt;Question 7&lt;/p&gt;
  &lt;div style=&quot;width:55%; float:left;&quot;&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;avel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;avel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;var x = y;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  &lt;/div&gt;

  &lt;div class=&quot;quiz-holder&quot;
       data-answers=&apos;[&quot;1&quot;,&quot;2&quot;,&quot;Other&quot;]&apos;
       data-correct=&apos;Other&apos;
       data-label=&apos;What does f(1) return?&apos;&gt;
  &lt;/div&gt;

  &lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;

  &lt;p class=&quot;quiz-explanation&quot;&gt;
    &lt;code&gt;f(1) --&amp;gt; &lt;span style=&quot;color: red&quot;&gt;ReferenceError: y is not defined&lt;/span&gt;&lt;/code&gt;&lt;br/&gt;
    What&apos;s going on here?  We defined a variable and it isn&apos;t visible
    like it was before, and all we did was rename &lt;code&gt;eval&lt;/code&gt;.
    Let&apos;s try a simpler example.
  &lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;quiz-question&quot;&gt;
  &lt;p&gt;Question 8&lt;/p&gt;
  &lt;div style=&quot;width:55%; float:left;&quot;&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;avel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;avel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;var x = 2;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  &lt;/div&gt;

  &lt;div class=&quot;quiz-holder&quot;
       data-answers=&apos;[&quot;1&quot;,&quot;2&quot;,&quot;Other&quot;]&apos;
       data-correct=&apos;1&apos;
       data-label=&apos;What does f(1) return?&apos;&gt;
  &lt;/div&gt;

  &lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;

  &lt;p class=&quot;quiz-explanation&quot;&gt;
    &lt;code&gt;f(1) === 1&lt;/code&gt;&lt;br/&gt;
    OK, so somehow we aren&apos;t seeing the assignment to &lt;code&gt;x&lt;/code&gt;
    either...  Let&apos;s try making one more observation:
  &lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;quiz-question&quot;&gt;
  &lt;p&gt;Question 9&lt;/p&gt;
  &lt;div style=&quot;width:55%; float:left;&quot;&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;avel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;avel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;var x = 2;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  &lt;/div&gt;

  &lt;div class=&quot;quiz-holder&quot;
       data-answers=&apos;[&quot;1&quot;,&quot;2&quot;,&quot;Other&quot;]&apos;
       data-correct=&apos;2&apos;
       data-label=&apos;What is the value of x after f is called?&apos;&gt;
  &lt;/div&gt;

  &lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;

  &lt;p class=&quot;quiz-explanation&quot;&gt;
    &lt;code&gt;x === 2&lt;/code&gt;&lt;br/&gt;
    Whoa!  So that eval changed the &lt;code&gt;x&lt;/code&gt; &lt;em&gt;in the global
    scope&lt;/em&gt;.  This is what the specification refers to as an
    &lt;em&gt;indirect eval&lt;/em&gt;; when the call to &lt;code&gt;eval&lt;/code&gt; doesn&apos;t
    use a direct reference to the variable &lt;code&gt;eval&lt;/code&gt;.
  &lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;quiz-question&quot;&gt;
  &lt;p&gt;Question 10 (On the home stretch!)&lt;/p&gt;
  &lt;div style=&quot;width:55%; float:left;&quot;&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;use strict&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;var x = 2;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  &lt;/div&gt;

  &lt;div class=&quot;quiz-holder&quot;
       data-answers=&apos;[&quot;1,2&quot;,&quot;2,2&quot;,&quot;1,Unbound&quot;,&quot;2,Unbound&quot;]&apos;
       data-correct=&apos;1,Unbound&apos;
       data-label=&apos;What does f(1) return, and what is global x afterwards?&apos;&gt;
  &lt;/div&gt;

  &lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;

  &lt;p class=&quot;quiz-explanation&quot;&gt;
    &lt;code&gt;f(1) === 1&lt;/code&gt;&lt;br/&gt;
    Before, when we had &lt;code&gt;&quot;use strict&quot;;&lt;/code&gt; &lt;em&gt;inside&lt;/em&gt; the
    &lt;code&gt;eval&lt;/code&gt;, we saw that the variable declarations did not
    escape.  Here, the &lt;code&gt;&quot;use strict&quot;;&lt;/code&gt; is outside, but we see
    the same thing: the value of
    &lt;code&gt;1&lt;/code&gt; simply flows through to the return statement
    unaffected.  Second, we know that we aren&apos;t doing the same thing as
the &lt;em&gt;indirect&lt;/em&gt; &lt;code&gt;eval&lt;/code&gt; from the previous question,
because we didn&apos;t affect the global scope.
  &lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;quiz-question&quot;&gt;
  &lt;p&gt;Question 11 (last one!)&lt;/p&gt;
  &lt;div style=&quot;width:55%; float:left;&quot;&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;use strict&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;avel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;avel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;var x = 2;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  &lt;/div&gt;

  &lt;div class=&quot;quiz-holder&quot;
       data-answers=&apos;[&quot;1,2&quot;,&quot;2,2&quot;,&quot;1,Unbound&quot;,&quot;2,Unbound&quot;]&apos;
       data-correct=&apos;1,2&apos;
       data-label=&apos;What does f(1) return, and what is global x afterwards?&apos;&gt;
  &lt;/div&gt;

  &lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;

  &lt;p class=&quot;quiz-explanation&quot;&gt;
    &lt;code&gt;f(1) === 1&lt;/code&gt;&lt;br/&gt;
    &lt;code&gt;x === 2&lt;/code&gt;&lt;br/&gt;
    Unlike in the previous question, this indirect &lt;code&gt;eval&lt;/code&gt; has
    the same behavior as before: it affects the global scope.  The
presence of a &lt;code&gt;&quot;use strict&quot;;&lt;/code&gt; appears to mean something different to an
indirect versus a direct &lt;code&gt;eval&lt;/code&gt;.
  &lt;/p&gt;
&lt;/div&gt;


&lt;div id=&quot;quiz-results&quot; style=&quot;display: none; margin-top: 10pt; font-weight:bold;&quot;&gt;
&lt;/div&gt;

&lt;h3&gt;Capturing all the Evals&lt;/h3&gt;

&lt;p&gt;
We saw three factors that could affect the behavior of &lt;code&gt;eval&lt;/code&gt;
above:
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
Whether the code passed to &lt;code&gt;eval&lt;/code&gt; was in &lt;code&gt;strict&lt;/code&gt; mode;
&lt;/li&gt;
&lt;li&gt;
Whether the code surrounding the &lt;code&gt;eval&lt;/code&gt; was in
&lt;code&gt;strict&lt;/code&gt; mode; and
&lt;/li&gt;
&lt;li&gt;
Whether the &lt;code&gt;eval&lt;/code&gt; was &lt;em&gt;direct&lt;/em&gt; or &lt;em&gt;indirect&lt;/em&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Each of these is a binary choice, so there are eight potential
configurations for an &lt;code&gt;eval&lt;/code&gt;.  Each of the eight cases
specifies both:
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
Whether the &lt;code&gt;eval&lt;/code&gt; sees the current scope or the global
one;
&lt;/li&gt;
&lt;li&gt;
Whether variables introduced in the &lt;code&gt;eval&lt;/code&gt; are seen
outside of it.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
We can crisply describe all of these choices in a table:
&lt;/p&gt;

&lt;table style=&quot;text-align:left;&quot;&gt;
&lt;tr&gt;
  &lt;th class=&quot;bluehead&quot;&gt;Strict outside?&lt;/th&gt;
  &lt;th class=&quot;bluehead&quot;&gt;Strict inside?&lt;/th&gt;
  &lt;th class=&quot;bluehead&quot;&gt;Direct or Indirect?&lt;/th&gt;
  &lt;th class=&quot;redhead&quot;&gt;Local or global scope?&lt;/th&gt;
  &lt;th class=&quot;redhead&quot;&gt;Affects scope?&lt;/th&gt;
&lt;/tr&gt;
&lt;tr class=&quot;bluerow boldrow&quot;&gt;
  &lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Indirect&lt;/td&gt;&lt;td&gt;Global&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;bluerow boldrow&quot;&gt;
  &lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Indirect&lt;/td&gt;&lt;td&gt;Global&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;redrow&quot;&gt;
  &lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Indirect&lt;/td&gt;&lt;td&gt;Global&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;redrow&quot;&gt;
  &lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Indirect&lt;/td&gt;&lt;td&gt;Global&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;bluerow boldrow&quot;&gt;
  &lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Direct&lt;/td&gt;&lt;td&gt;Local&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;bluerow boldrow&quot;&gt;
  &lt;td&gt;No&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Direct&lt;/td&gt;&lt;td&gt;Local&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;bluerow boldrow&quot;&gt;
  &lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Direct&lt;/td&gt;&lt;td&gt;Local&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;redrow&quot;&gt;
  &lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;Direct&lt;/td&gt;&lt;td&gt;Local&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;
Rows where &lt;code&gt;eval&lt;/code&gt; can affect some scope are shown in red
(where it cannot is blue),
and rows where the string passed to &lt;code&gt;eval&lt;/code&gt; is strict mode code are in
bold.
Some patterns emerge here that make some of the design decisions of
&lt;code&gt;eval&lt;/code&gt; clear.  For example:
&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If the &lt;code&gt;eval&lt;/code&gt; is &lt;em&gt;indirect&lt;/em&gt; it always uses
global scope; if &lt;em&gt;direct&lt;/em&gt; it always uses local scope.
  &lt;/li&gt;

  &lt;li&gt;If the string passed to &lt;code&gt;eval&lt;/code&gt; is strict mode code,
then variable declarations will not be seen outside the
&lt;code&gt;eval&lt;/code&gt;.&lt;/li&gt;

  &lt;li&gt;An indirect &lt;code&gt;eval&lt;/code&gt; behaves the same regardless of the
strictness of its context, while direct &lt;code&gt;eval&lt;/code&gt; is sensitive
to it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Engineering &lt;code&gt;eval&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;
To specify &lt;code&gt;eval&lt;/code&gt;, we need to somehow both detect these
different configurations, and evaluate code with the right combination
of visible environment and effects.  To do so, we start with a flexible
primitive that lets us evaluate code in an environment expressed as an
object:&lt;/p&gt;

&lt;pre&gt;
internal-eval(string, env-object)
&lt;/pre&gt;

&lt;p&gt;
This &lt;code&gt;internal-eval&lt;/code&gt; expects &lt;code&gt;env-object&lt;/code&gt; to be an
object whose fields represent the environment to evaluate in.  No
identifiers other than those in the passed-in environment are bound.
For example, a call like:
&lt;/p&gt;

&lt;pre&gt;
internal-eval(&quot;x + y&quot;, { &quot;x&quot; : 2, &quot;y&quot; : 5 })
&lt;/pre&gt;

&lt;p&gt;Would evaluate to &lt;code&gt;7&lt;/code&gt;, using the values of the
&lt;code&gt;&quot;x&quot;&lt;/code&gt; and &lt;code&gt;&quot;y&quot;&lt;/code&gt; fields from the environment object as the
bindings for the identifiers &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;.  With
this core primitive, we have the control we need to implement all the
different versions of &lt;code&gt;eval&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt; In &lt;a href=&quot;https://blog.brownplt.org/2011/11/11/s5-javascript-semantics.html&quot;&gt;previous&lt;/a&gt;
&lt;a href=&quot;https://blog.brownplt.org/2011/09/29/js-essence.html&quot;&gt;posts&lt;/a&gt;, we talked about the
overall strategy of our evaluator for JavaScript.  The relevant
high-level point for this discussion is that we define a core language,
dubbed S5, that contains only the essential features of JavaScript.
Then, we define a source-to-source transformer, called &lt;em&gt;desugar&lt;/em&gt;,
that converts JavaScript programs to S5 programs.  Since our evaluator
is defined only over S5, we need to &lt;em&gt;use desugar&lt;/em&gt; in our
interpreter to perform the evaluation step.  Semantically, the
evaluation of &lt;code&gt;internal-eval&lt;/code&gt; is then: &lt;/p&gt;

&lt;pre&gt;
internal-eval(string, env-object) -&amp;gt; &lt;em&gt;desugar&lt;/em&gt;(string)[x&lt;sub&gt;1&lt;/sub&gt; / v&lt;sub&gt;1&lt;/sub&gt;, ...]
  for each x&lt;sub&gt;1&lt;/sub&gt; : v&lt;sub&gt;1&lt;/sub&gt; in env-object
  (where [x / v] indicates substitution)
&lt;/pre&gt;

&lt;p&gt;It is the combination of &lt;em&gt;desugar&lt;/em&gt; and the customizable
environment argument to &lt;code&gt;internal-eval&lt;/code&gt; that let us implement
all of JavaScript&apos;s &lt;code&gt;eval&lt;/code&gt; forms.  We actually
&lt;em&gt;desugar&lt;/em&gt; all calls to JavaScript&apos;s &lt;code&gt;eval&lt;/code&gt; into a
function call defined in S5 called &lt;code&gt;maybeDirectEval&lt;/code&gt;, which
performs all the necessary checks to construct the correct environment
for the &lt;code&gt;eval&lt;/code&gt;.
&lt;/p&gt;

&lt;h3&gt;Leveraging S5&apos;s Eval&lt;/h3&gt;

&lt;p&gt;
With our implementation of &lt;code&gt;eval&lt;/code&gt;, we have made progress on a
few fronts.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Analyzing more JavaScript:&lt;/b&gt;  We can now tackle more programs
than any of our prior formal semantics for JavaScript.  For example, we
can actually &lt;em&gt;run&lt;/em&gt; all of the complicated &lt;code&gt;eval&lt;/code&gt;s in
&lt;a href=&quot;https://code.google.com/p/es-lab/&quot;&gt;Secure ECMAScript&lt;/a&gt;, and
&lt;a href=&quot;http://cs.brown.edu/~justinpombrio/ses/ses-heap.html&quot;&gt;print the
heap&lt;/a&gt; inside a use of a sandboxed &lt;code&gt;eval&lt;/code&gt;.  This enables
new kinds of analyses that we haven&apos;t been able to perform before.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Understanding scripting languages&apos; &lt;code&gt;eval&lt;/code&gt;:&lt;/b&gt; Other
scripting languages, like Ruby and Python, also have &lt;code&gt;eval&lt;/code&gt;.
Their implementations are closer to our &lt;code&gt;internal-eval&lt;/code&gt;, in
that they take dictionary arguments that specify the bindings that are
available inside the evaluation.  Is something like
&lt;code&gt;internal-eval&lt;/code&gt;, which was inspired by well-known semantic
considerations, a useful underlying mechanism to use to describe all of
these?
&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/brownplt/LambdaS5&quot;&gt;implementation&lt;/a&gt;
of S5 is open-source, and a &lt;a
href=&quot;http://cs.brown.edu/research/plt/dl/s5/&quot;&gt;detailed report&lt;/a&gt; of
our strategy and test results is appearing at the Dynamic Languages
Symposium.  Check them out if you&apos;d like to learn more!
&lt;/p&gt;

&lt;script src=&quot;https://blog.brownplt.org/js/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://blog.brownplt.org/js/quiz.js&quot;&gt;&lt;/script&gt;

</content>
 </entry>
 
 <entry>
   <title>Progressive Types</title>
   <link href="http://blog.brownplt.org/2012/09/01/progressive-types.html"/>
   <updated>2012-09-01T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2012/09/01/progressive-types</id>
   <content type="html">&lt;p&gt;
Adding types to untyped languages has been studied extensively, and with good 
reason.  Type systems offer developers strong static guarantees about the behavior 
of their programs, and adding types to untyped code allows developers to reap 
these benefits without having to rewrite their entire code base.  However, these 
guarantees come at a cost. Retrofitting types on to untyped code can be an onerous 
and time-consuming process. In order to mitigate this cost, researchers have 
developed methods to type partial programs or sections of programs, or to allow looser 
guarantees from the type system.
(&lt;a href=&quot;http://www.cs.colorado.edu/~siek/pubs/pubs/2006/siek06:_gradual.pdf&quot;&gt;Gradual typing&lt;/a&gt;
and &lt;a href=&quot;ftp://ftp.cs.cmu.edu/usr/rwh/www/home/courses/refinements/papers/WrightCartwright97/toplas.pdf&quot;&gt;
soft typing&lt;/a&gt; are some examples.) This reduces the up-front cost of typing a program.
&lt;/p&gt;

&lt;p&gt;
However, these approaches only address a part of the problem. Even if the programmer is willing
to expend the effort to type the program, he still cannot control what counts as an 
acceptable program; that is determined by the type system. This 
significantly reduces the flexibility of the language and forces the programmer to work within
a very strict framework. To demonstrate this, observe the following program in Racket...
&lt;/p&gt;

&lt;pre id=&quot;untypedEx&quot;&gt;
#lang racket

(define (gt2 x y)
  (&gt; x y))
&lt;/pre&gt;

&lt;p&gt;
...and its Typed Racket counterpart.
&lt;/p&gt;

&lt;pre id=&quot;typedEx&quot;&gt;
#lang typed/racket

(: gt2 (Number Number -&gt; Boolean))
(define (gt2 x y)
  (&gt; x y))
&lt;/pre&gt;

&lt;p&gt;
The typed example above, which appears to be logically typed, fails to type-check. 
This is due to the sophistication with which Typed Racket handles numbers. It can distinguish between 
complex numbers and real numbers, integers and  non-integers, even positive and negative integers. In 
this system, &lt;i&gt;Number&lt;/i&gt; is actually an alias for &lt;i&gt;Complex&lt;/i&gt;. This makes sense in that complex 
numbers are in fact the super type of all other numbers.  
However, it would also be reasonable to assume that &lt;i&gt;Number&lt;/i&gt; means &lt;i&gt;Real&lt;/i&gt;, because that&apos;s
what people tend to think of when they think &amp;ldquo;number&amp;rdquo;. Because of this, a developer may expect 
all functions over real numbers to work over &lt;i&gt;Number&lt;/i&gt;s. However, this is not the case. Greater-than, 
which is defined over reals, cannot be used with &lt;i&gt;Number&lt;/i&gt; because it is not defined over complex numbers. 
Now, this could be resolved by changing the type of &lt;font face=&quot;Courier, sans-serif&quot; size=&quot;-1&quot;&gt;gt2&lt;/font&gt; 
to take &lt;i&gt;Real&lt;/i&gt;s, rather than &lt;i&gt;Number&lt;/i&gt;s. But then consider this program:

&lt;pre id=&quot;expandedEx&quot;&gt;
#lang typed/racket

(: plus (Number Number -&gt; Number))
(define (plus x y)
  (+ x y))
;Looks fine so far...

(: gt2 (Real Real -&gt; Boolean))
(define (gt2 x y)
  (&gt; x y))
;...Still ok...

(gt2 (plus 3 4) 5)
;...Here (plus 3 4) evaluates to a Number which causes gt2 to give 
;the type error &amp;ldquo;Expected Real but got Complex&amp;rdquo;.
&lt;/pre&gt;

Now, in order to make this program type, we would have to adjust 
&lt;font face=&quot;Courier, sans-serif&quot; size=&quot;-1&quot;&gt;plus&lt;/font&gt; to return &lt;i&gt;Real&lt;/i&gt;s, even though it works with 
it&apos;s current typing! And we&apos;d have to do the same for every program that calls 
&lt;font face=&quot;Courier, sans-serif&quot; size=&quot;-1&quot;&gt;plus&lt;/font&gt;. This can cause a ripple effect through the 
program, making typing the program labor-intensive, despite the fact that the program will actually
run just fine on some inputs, which may be all we care about. But we still have to jump through 
hoops to get the program to run at all!
&lt;/p&gt;

&lt;p&gt;
In the above example, the type system in Typed Racket requires the programmer to ensure
that there are no runtime errors caused by using a complex number where a real number is 
expected, even if it means significant extra programming effort.  There are cases, however, 
where type systems do not provide guarantees because it would cross the threshold of &lt;i&gt;too&lt;/i&gt; 
much work for programmers.  One such guarantee is ensuring that vector references are always 
given positive integer inputs. The Typed Racket type system does not offer this guarantee 
because of the required programming effort, and so it traded that particular guarantee for
convenience and ease of programming.
&lt;/p&gt;

&lt;p&gt;
In both these cases, type systems are trying to determine the best balance betwen safety 
and convenience. However, the best a system can do is choose either safety or convenience 
and apply that to all programs. Vector references cannot be checked in any program, because 
it isn&apos;t worth the extra engineering effort, whereas all programs must be checked for number 
realness, because it&apos;s worth the extra engineering effort. This seems pretty arbirtary! 
Type systems are trying to guess at what the developer might want, instead of just asking. 
However, the developer has a much better idea of which checks are relevant and important for a 
specific program and which are irrelevant or unimportant. The type system should leverage this 
information and offer the useful guarantees without requiring unhelpful ones.
&lt;/p&gt;

&lt;h3&gt;Progressive Types&lt;/h3&gt;

&lt;p&gt;
To this end, we have developed &lt;i&gt;progressive&lt;/i&gt; types, which allow the developer to 
require type guarantees that are significant to the program, and ignore those 
that are irrelevant.  From the total set of possible type errors, the developer would 
select which among them must be detected as compile time type errors, and which should be 
allowed to possibly cause runtime failures. In the above example, the developer could allow errors 
caused by treating a &lt;i&gt;Number&lt;/i&gt; as a &lt;i&gt;Real&lt;/i&gt; at runtime, trusting that 
they will never occur or that it won&apos;t be catastrophic if they do or that the particular error 
is orthogonal to the reasons for type-checking the program at all. Thus, the developer can
disregard an insignificant error while still reaping the 
benefits of the rest of the type system. This addresses a problem that underlies all type systems: 
The programmer doesn&apos;t get to choose which classes of programs are &amp;ldquo;good&amp;rdquo; and which 
are &amp;ldquo;bad.&amp;rdquo; Progressive types give the programmer that control.
&lt;/p&gt;

&lt;p&gt;
In order to allow this, the type system has an allowed error set, &amp;#937;, in addition to the 
type environment. So while a traditional typing rule takes the form &amp;#915;&amp;#8866;&lt;i&gt;e&lt;/i&gt;:&amp;#964;, 
a rule in progressive type would take the form &amp;#937;;&amp;#915;&amp;#8866;&lt;i&gt;e&lt;/i&gt;:&amp;#964;. Here, &amp;#937 is the set
of errors the developer wants to allow to cause runtime failures. Expressions may evaluate to errors, and 
if those errors are in &amp;#937;, the expression will type to &amp;#8869;, otherwise it will fail to 
type. This is reflected in the progress theorem that goes along with the type system.
&lt;/p&gt;

&lt;p&gt;
If Typed Racket were a progressively typed language, the above program would type only if 
the programmer had selected &amp;ldquo;Expected &lt;i&gt;Real&lt;/i&gt;, but got &lt;i&gt;Complex&lt;/i&gt;&amp;rdquo; to 
be in &amp;#937;. This means that if numerical calculations are really orthogonal to the point 
of the program, or there are other checks in place insuring the function will only get the right type of 
input, the developer can just tell the type checker not to worry about those errors! However, if it&apos;s 
important to ensure that complex numbers never appear where reals are required, the developer can tell 
the type checker to detect those errors. Thus the &lt;i&gt;programmer&lt;/i&gt; can determine what constitutes a 
&amp;ldquo;good&amp;rdquo; program, rather than working around a different, possibly inconvenient, 
definition of &amp;ldquo;good&amp;rdquo;. By passing this control over to the developer, progressive
type systems allow the balance between ease of engineering and saftey to be set at a level 
appropriate to the program.
&lt;/p&gt;

&lt;p&gt;
Progressive typing differs from gradual typing in that while gradual typing allows the developer to 
type portions of a program with a fixed type system, progressive types instead allow the developer 
to vary the guarantees offered by the type system. Further, like soft typing, progressive typing allows
for runtime errors instead of static guarantees, but unlike soft typing, it restricts which classes 
of runtime failures are allowed to occur. Because our system allows programmers to progressively adjust 
the restrictions imposed by the type system, either to loosen or  tighten them, they can reap many of 
the flexibility benefits of a dynamic languages, but get static guarantees of a type system in the way best 
suited to each of their programs or preferences.
&lt;/p&gt;

&lt;p&gt;
If you are interested in learning more about progressive types, look 
&lt;a href=&quot;http://www.cs.brown.edu/~sk/Publications/Papers/Published/pqk-progressive-types/&quot;&gt;here&lt;/a&gt;.
&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Modeling DOM Events</title>
   <link href="http://blog.brownplt.org/2012/07/17/domevents.html"/>
   <updated>2012-07-17T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2012/07/17/domevents</id>
   <content type="html">&lt;style&gt;
  div.example {
    background: #DDD;
    width: 20em;
    border: 2px solid #666;
    margin: 1em;
    padding: 1em;
  }
&lt;/style&gt;
&lt;script&gt;
//&lt;![CDATA[
  function createExample(ex) {
    var div = document.getElementById(ex.dataset.example);
    ex.innerHTML = div.textContent;
    var scripts = ex.getElementsByTagName(&quot;script&quot;);
    for (var j = 0; j &lt; scripts.length; j++) {
      var script = scripts[j];
      var s = document.createElement(&quot;script&quot;);
      s.innerHTML = script.innerHTML;
      script.parentNode.replaceChild(s, script);
    }
  }
  function createExamples() {
    var examples = document.querySelectorAll(&quot;div.example&quot;);
    for (var i = 0; i &lt; examples.length; i++) {
      var ex = examples[i];
      createExample(ex);
      var reset = document.createElement(&quot;button&quot;);
      reset.textContent = &quot;Reset example&quot;;
      reset.addEventListener(&quot;click&quot;, function() { createExample(this.previousSibling); });
      ex.parentNode.insertBefore(reset, ex.nextSibling);
    }
  }
  window.addEventListener(&quot;load&quot;, createExamples);
//]]&gt;
&lt;/script&gt;

&lt;p&gt;In previous posts, we&amp;rsquo;ve talked about our group&amp;rsquo;s work on
  providing an &lt;a href=&quot;https://blog.brownplt.org/2011/09/29/js-essence.html&quot;&gt;operational semantics for
  JavaScript&lt;/a&gt;, including the &lt;a href=&quot;/2011/11/11/s5-javascript-semantics.html&quot;&gt;
  newer features of the language&lt;/a&gt;.  While that work is useful for
  understanding the language, most JavaScript programs
  don&amp;rsquo;t run in a vacuum: they run in a browser, with a rich API to
  access the contents of the page.&lt;/p&gt;

&lt;p&gt;That API, known as the Document Object Model (or DOM), consists of
  several parts:
&lt;ul&gt;
  &lt;li&gt;A graph of objects encoding the structure of page (This graph
    is optimistically called a &quot;tree&quot; since the HTML
    markup is indeed tree-shaped, but this graph has extra pointers
    between objects.),&lt;/li&gt;
  &lt;li&gt;Methods to manipulate the HTML tree structure,&lt;/li&gt;
  &lt;li&gt;A sophisticated event model to allow scripts to react to user
    interactions.&lt;/li&gt;
&lt;/ul&gt;
These three parts of the DOM interact with one other, making reasoning
about any one of them in isolation challenging.  Moreover, the specs
describing them are long, heavily self-referential, and difficult to
understand incrementally.  So what to do?&lt;/p&gt;

&lt;h3&gt;What makes &lt;i&gt;this&lt;/i&gt; event programming so special?&lt;/h3&gt;
&lt;p&gt;To a first approximation, the execution of every web page looks
  roughly like: load the markup of the page,
  load scripts, set up lots of event handlers &amp;hellip; and wait.
  For events.  To fire.  Accordingly, to
  understand the control flow of a page, we have to understand
  what happens when events fire.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with this: &lt;/p&gt;
&lt;pre id=&quot;ex1&quot;&gt;
  &amp;lt;div id=&quot;d1&quot;&amp;gt;
    In outer div
    &amp;lt;p id=&quot;p1&quot;&amp;gt;
      In paragraph in div.
      &amp;lt;span id=&quot;s1&quot; style=&quot;background:white;&quot;&amp;gt;
        In span in paragraph in div.
      &amp;lt;/span&amp;gt;
    &amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;script&amp;gt;
    document.getElementById(&quot;s1&quot;).addEventListener(&quot;click&quot;,
      function() { this.style.color = &quot;red&quot;; });
  &amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;div class=&quot;example&quot; data-example=&quot;ex1&quot;&gt;
  Requires JavaScript enabled to view the example
&lt;/div&gt;
&lt;p&gt;If you click on the text &quot;In span in paragraph in div&quot;
the &lt;i&gt;event listener&lt;/i&gt; that gets added to element &lt;code&gt;span#s1&lt;/code&gt; is
triggered by the click, and turns the text red. But consider the
slightly more complicated example:&lt;/p&gt;
&lt;pre id=&quot;ex2&quot;&gt;
  &amp;lt;div id=&quot;d2&quot;&amp;gt;
    In outer div
    &amp;lt;p id=&quot;p2&quot;&amp;gt;
      In paragraph in div.
      &amp;lt;span id=&quot;s2&quot; style=&quot;background:white;&quot;&amp;gt;
        In span in paragraph in div.
      &amp;lt;/span&amp;gt;
    &amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;script&amp;gt;
    document.getElementById(&quot;d2&quot;).addEventListener(&quot;click&quot;,
      function() { this.style.color = &quot;red&quot;; });
    document.getElementById(&quot;s2&quot;).addEventListener(&quot;click&quot;,
      function() { this.style.color = &quot;blue&quot;; });
  &amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;div class=&quot;example&quot; data-example=&quot;ex2&quot;&gt;
  Requires JavaScript enabled to view the example
&lt;/div&gt;
&lt;p&gt;Now, clicking anywhere in the box will turn all the text red.  That
  makes sense: we just clicked on the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;
  element, so its listener fires.  But clicking on the &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; will turn
  it blue and still turn the rest red.  Why?  We didn&amp;rsquo;t click on
  the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;!  Well, not directly&amp;hellip;&lt;/p&gt;
&lt;p&gt;The key feature of event dispatch, as implemented for the DOM, is that
  it takes advantage of the page structure.  Clicking on an element of
  the page (or typing into a text box, moving the mouse over an
  element, etc.) will cause an event to fire &quot;at&quot; that element: the
  element is the &lt;i&gt;target&lt;/i&gt; of the event, and any event listener
  installed for that event on that target node will be called.  But in
  addition, the event will also trigger event listeners on
  the &lt;i&gt;ancestors&lt;/i&gt; of the target node: this is called
  the &lt;i&gt;dispatch path&lt;/i&gt;.  So in the example above,
  because &lt;code&gt;div#d2&lt;/code&gt; is an ancestor of &lt;code&gt;span#s2&lt;/code&gt;,
  its event listener is also invoked, turning the text red.&lt;/p&gt;

&lt;h3&gt;What Could Possibly Go Wrong?&lt;/h3&gt;
&lt;p&gt;In a word: mutation.  The functions called as event listeners are
  arbitrary JavaScript code, which can do anything they want to the
  state of the page, including modifying the DOM.  So what might happen?
&lt;ul&gt;
  &lt;li&gt;The event listener might move the current target in the page.
    What happens to the dispatch path?&lt;/li&gt;
  &lt;li&gt;The event listener adds (or removes) other listeners for the
    event being dispatched.  Should newly installed listeners be
    invoked before or after existing ones? Should those listeners even
    be called?&lt;/li&gt;
  &lt;li&gt;The event listener tries to cancel event dispatch.  Can it
    do so?&lt;/li&gt;
  &lt;li&gt;The listener tries to (programmatically) fire another event while the current
    one is active.  Is event dispatch reentrant?&lt;/li&gt;
  &lt;li&gt;There are legacy mechanisms to add event &quot;handlers&quot;
    as well as listeners.  How should they interact with
    listeners?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Modeling Event Dispatch&lt;/h3&gt;
&lt;p&gt;Continuing our group&amp;rsquo;s theme of reducing a complicated, real-world
  system to a simpler operational model, we developed an idealized
  version of event dispatch
  in &lt;a href=&quot;http://redex.racket-lang.org&quot;&gt;PLT Redex&lt;/a&gt;, a
  domain-specific language embedded in Racket for specifying
  operational semantics.  Because we are focusing on exactly how event
  dispatch works, our model does &lt;i&gt;not&lt;/i&gt; include all of JavaScript,
  nor does it need to&amp;mdash;instead, it includes a miniature statement
  language containing the handful of DOM APIs that manipulate events.
  Our model does &lt;i&gt;not&lt;/i&gt; include all the thousands of DOM
  properties and methods, instead including just a simplified
  tree-structured heap of nodes: this is all the structure we need to
  faithfully model the dispatch path of an event.&lt;/p&gt;
&lt;p&gt;Our model is based on
  the &lt;a href=&quot;http://www.w3.org/TR/DOM-Level-3-Events/&quot;&gt;DOM Level 3
  Events&lt;/a&gt; specification.  It expresses the key behaviors of event
  dispatch, and does so far more compactly than the spec: roughly 1000
  lines of commented Redex code replace several pages&amp;rsquo; worth of
  (at times self-contradictory!) requirements that are spread
  throughout a spec over a hundred pages long.  From this concise
  model, for example, we can easily extract a state machine describing
  the key stages of dispatch:
  &lt;figure&gt;&lt;img class=&quot;center&quot; style=&quot;width:30em&quot; src=&quot;https://blog.brownplt.org/img/event-dispatch.png&quot; /&gt;&lt;/figure&gt; From this state machine,
  it&amp;rsquo;s much easier to answer the questions raised above,
  precisely and formally.  For example, if an event listener moves the
  event target in the page, nothing happens to the dispatch path: only
  the first state of the machine constructs the dispatch path, while
  all the others just read from it.  Done!  It&amp;rsquo;s unfortunate that
  this state machine isn&apos;t sketched in the spec anywhere&amp;hellip;&lt;/p&gt;

&lt;p&gt;Moreover, the model is &lt;i&gt;executable&lt;/i&gt;: Redex allows us to
  construct test cases&amp;mdash;randomly, systematically, or ad-hoc, as
  we choose&amp;mdash;and then run them through our model and see what
  output it produces.  Even better, we can export our tests to HTML
  and JavaScript, and run them in real browsers and compare results:
  &lt;figure&gt;
    &lt;img class=&quot;center&quot; style=&quot;width:30em&quot; src=&quot;https://blog.brownplt.org/img/event-testing.png&quot; /&gt;
    &lt;figcaption&gt;Comparing a test model (tree structure, event
    listeners, and an event to be fired) in our semantics, and in
    various browsers.&lt;/figcaption&gt;
  &lt;/figure&gt;
  Most importantly, our model agrees with all browsers on most test
  cases: this gives us confidence that our model is faithful to the
  intent of the spec.  But not &lt;i&gt;all&lt;/i&gt; test cases&amp;mdash;not too
  surprisingly, we identified examples where real-world browsers
  differ in their behavior.  Under our reading of the spec, at least
  one of these browsers is wrong&amp;mdash;but since the spec is so
  intricate, it is easy to see why browsers have a hard time agreeing
  in all cases!&lt;/p&gt;

&lt;h3&gt;What&amp;rsquo;s Done&lt;/h3&gt;

&lt;p&gt;Here&amp;rsquo;s what we&amp;rsquo;ve got so far:&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;A &lt;a href=&quot;http://www.cs.brown.edu/research/plt/dl/domsemantics/redex-domv2.rkt&quot;&gt;PLT
    Redex model&lt;/a&gt; of event dispatch,&lt;/li&gt;


&lt;li&gt;An &lt;a
href=&quot;http://www.cs.brown.edu/research/plt/dl/domsemantics/level3spec.html&quot;&gt;annotated
    copy of the DOM Level 3 Events spec, showing exactly which lines
    of our model correspond to which text in the spec&lt;/a&gt;,
  and&lt;/li&gt;

&lt;li&gt;A &lt;a
href=&quot;http://www.cs.brown.edu/research/plt/dl/domsemantics/domsemantics.pdf&quot;&gt;paper
    describing the model (and some applications of it) in greater detail&lt;/a&gt;.&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;What&amp;rsquo;s Next&lt;/h3&gt;

&lt;p&gt;Since our original JavaScript semantics was also written in Redex,
  we can combine our model of event dispatch with the JavaScript one,
  for a much higher-fidelity model of what event listeners can do in a
  browser setting.  Then of course there are further applications, such as
  building a precise control-flow analysis of web pages and analyzing
  their code.  And other uses?  If you&amp;rsquo;re interested in using
  our model, let us know!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Mechanized LambdaJS</title>
   <link href="http://blog.brownplt.org/2012/06/04/lambdajs-coq.html"/>
   <updated>2012-06-04T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2012/06/04/lambdajs-coq</id>
   <content type="html">&lt;p&gt;
&lt;b&gt;See &lt;a href=&quot;http://lambda-the-ultimate.org/node/4555&quot;&gt;the discussion&lt;/a&gt;
on Lambda the Ultimate about this work.&lt;/b&gt;
&lt;/p&gt;

&lt;p&gt;In an &lt;a href=&quot;https://blog.brownplt.org/2011/09/29/js-essence.html&quot;&gt;earlier post&lt;/a&gt;, we introduced
&amp;lambda;&lt;sub&gt;JS&lt;/sub&gt;, our operational semantics for JavaScript. Unlike many
other operational semantics, &amp;lambda;&lt;sub&gt;JS&lt;/sub&gt; is no toy, but strives to
correctly model JavaScript&apos;s messy details. To validate these claims, we test
&amp;lambda;&lt;sub&gt;JS&lt;/sub&gt; with randomly
generated tests and with portions of the Mozilla JavaScript test suite.&lt;/p&gt;

&lt;p&gt;Testing is not enough. Despite our work, other researchers found a missing
case in &amp;lambda;&lt;sub&gt;JS&lt;/sub&gt;. Today, we&apos;re introducing Mechanized
&amp;lambda;&lt;sub&gt;JS&lt;/sub&gt;, which comes with a machine-checked proof of correctness,
using the &lt;a href=&quot;http://coq.inria.fr/&quot;&gt;Coq proof assistant&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Recap: The Structure of &amp;lambda;&lt;sub&gt;JS&lt;/sub&gt;&lt;/h3&gt;

&lt;p&gt;&amp;lambda;&lt;sub&gt;JS&lt;/sub&gt; has two key parts: an operational semantics and a
desugaring function. Our &lt;a href=&quot;https://blog.brownplt.org/2011/09/29/js-essence.html&quot;&gt;earlier post&lt;/a&gt;
discusses how we tackle the minutiae of JavaScript with our desugaring
function. This post focuses on the operational semantics, where others found a
bug, which now has a machine-checked proof of correctness.&lt;/p&gt;

&lt;p&gt;The operational semantics is typical of programming languages research. It
specifies the sequence of steps required to evaluate the program. For
example, the following sequence evaluates to a value:

&lt;pre&gt;
  { x: 2 + 3, y : 9 }[&quot;x&quot;] * (11 + 23)
&amp;rarr; { x: 5, y: 9 }[&quot;x&quot;] * (11 + 23)
&amp;rarr; 5 * (11 + 23)
&amp;rarr; 5 * 34
&amp;rarr; 170 
&lt;/pre&gt;

The sequence above evaluates expressions from left to right&amp;mdash;a detail
spelled out in the operational semantics.
&lt;/p&gt;

&lt;p&gt;Not all expressions reduce to values. For example, the following reduces to an error:

&lt;pre&gt;
  null[&quot;x&quot;]
&amp;rarr; err &quot;Cannot read property &apos;x&apos; of null&quot;
&lt;/pre&gt;

An operational semantics specifies exactly which errors may occur.&lt;/p&gt;

&lt;p&gt;Finally, an operational semantics allows some programs to run forever. This is a basic infinite loop, and its non-terminating reduction sequence:

&lt;pre&gt;
  while (true) { 1; }
&amp;rarr; if true then 1; while (true) { 1; } else undefined
&amp;rarr; 1; while (true) { 1; }
&amp;rarr; while (true) { 1; }
&amp;rarr; if true then 1; while (true) { 1; } else undefined
&amp;rarr; 1; while (true) { 1; }
&amp;hellip;
&lt;/pre&gt;

&lt;/p&gt;

&lt;p&gt;In general, these are the only three cases that the semantics should
allow&amp;mdash;an expression must either (1) evaluate to a value, (2) signal  an
error, or (3) not terminate. In fact, we can state that as a theorem.

&lt;p&gt;&lt;b&gt;Theorem 1 (Soundness).&lt;/b&gt; For all &amp;lambda;&lt;sub&gt;JS&lt;/sub&gt; programs,
&lt;i&gt;p&lt;/i&gt;, either:

&lt;ol&gt;

&lt;li&gt; &lt;i&gt;p &amp;rarr;* v&lt;/i&gt;,

&lt;li&gt; &lt;i&gt;p &amp;rarr;* &lt;b&gt;err&lt;/b&gt;&lt;/i&gt;, or

&lt;li&gt; &lt;i&gt;p &amp;rarr;* p&lt;sub&gt;2&lt;/sub&gt;&lt;/i&gt;, and there exists a &lt;i&gt;p&lt;sub&gt;3&lt;/sub&gt;&lt;/i&gt;
such that &lt;i&gt;p&lt;sub&gt;2&lt;/sub&gt; &amp;rarr; p&lt;sub&gt;3&lt;/sub&gt;&lt;/i&gt;.&lt;/li&gt;

&lt;/ol&gt;

&lt;/p&gt;

&lt;p&gt;This is a standard theorem worth proving for any language.
Since languages and their correctness proofs involve detailed, delicate designs and
decisions, the proofs are easy to do wrong, and tedious for humans to get right. If only computers could help.&lt;/p&gt;

&lt;h3&gt;PLT Redex: Lightweight Mechanization&lt;/h3&gt;

&lt;p&gt;We first developed &amp;lambda;&lt;sub&gt;JS&lt;/sub&gt; in &lt;a
href=&quot;http://redex.racket-lang.org/&quot;&gt;PLT Redex&lt;/a&gt;, a domain-specific language
embedded in Racket for specifying operational semantics.&lt;/p&gt;

&lt;p&gt;Redex brings dull semantics to life. It doesn&apos;t just make a semantics
executable, but also lets you visualize it.  For example, here is our first
example sequence in Redex (parentheses included):&lt;/p&gt;

&lt;img src=&quot;https://blog.brownplt.org/img/lambdajs-redex-viz.png&quot;&gt; 

&lt;p&gt;The visualizer is a lot of fun, and a very effective debugging tool. It helped us catch several bugs in the early design of &amp;lambda;&lt;sub&gt;JS&lt;/sub&gt;.&lt;/p&gt; 

&lt;p&gt;Redex can also generate &lt;a
href=&quot;http://www.eecs.northwestern.edu/~robby/pubs/papers/scheme2009-kf.pdf&quot;&gt;random
tests to exercise your semantics&lt;/a&gt;. Random testing caught several more bugs
in &amp;lambda;&lt;sub&gt;JS&lt;/sub&gt;.&lt;/p&gt;

&lt;h3&gt;Coq: A Machine-Checked Proof&lt;/h3&gt;

&lt;p&gt;Testing is not enough. We shipped &amp;lambda;&lt;sub&gt;JS&lt;/sub&gt; with a bug that
breaks the soundness theorem above. We didn&apos;t discover it for a year. &lt;a
href=&quot;http://www.ccs.neu.edu/home/dvanhorn/&quot;&gt;David van Horn&lt;/a&gt; and &lt;a
href=&quot;http://www.zerny.dk/&quot;&gt;Ian Zerny&lt;/a&gt; both reported it to us independently.
We&apos;d missed a case in the semantics, which caused certain terms to get &quot;stuck&quot;.
It turned out to be a &lt;a
href=&quot;https://github.com/brownplt/LambdaJS/commit/9a7e67ab896c8db3f12cdfe3aa6fe74e192b1b00&quot;&gt;simple
fix&lt;/a&gt;, but we were left wondering if anything else was left lurking.&lt;/p&gt;

&lt;p&gt;To gain further assurance, we  mechanized
&amp;lambda;&lt;sub&gt;JS&lt;/sub&gt; with the &lt;a
href=&quot;http://coq.inria.fr&quot;&gt;Coq proof assistant&lt;/a&gt;. The soundness theorem now
has a  &lt;a
href=&quot;https://github.com/brownplt/LambdaJS/blob/master/coq/LambdaJS.v&quot;&gt;machine-checked
proof of correctness&lt;/a&gt;. You still need to read the &lt;a
href=&quot;https://github.com/brownplt/LambdaJS/blob/master/coq/LambdaJS_Defs.v&quot;&gt;Coq
definition of &amp;lambda;&lt;sub&gt;JS&lt;/sub&gt;&lt;/a&gt; and ensure it matches your intuitions.
But once that&apos;s done, you can be confident that the proofs are valid.&lt;/p&gt;

&lt;p&gt;Doing this proof was surprisingly easy, once we&apos;d read &lt;a
href=&quot;http://www.cis.upenn.edu/~bcpierce/sf/&quot;&gt;Software Foundations&lt;/a&gt; and &lt;a
href=&quot;http://adam.chlipala.net/cpdt/&quot;&gt;Certified Programming with Dependent
Types&lt;/a&gt;. We&apos;d like to thank Benjamin Pierce and his co-authors, and Adam
Chlipala, for putting their books online.&lt;/p&gt;

&lt;h3&gt;What&apos;s Done&lt;/h3&gt;

&lt;p&gt;Here&apos;s what we&apos;ve got so far:&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;A &lt;a href=&quot;https://github.com/brownplt/LambdaJS/blob/master/Redex/jscore.ss&quot;&gt;PLT Redex model&lt;/a&gt;,&lt;/li&gt;


&lt;li&gt;A &lt;a
href=&quot;https://github.com/brownplt/LambdaJS/blob/master/coq/LambdaJS_Defs.v&quot;&gt;Coq
model&lt;/a&gt;, and&lt;/li&gt;

&lt;li&gt;A &lt;a
href=&quot;https://github.com/brownplt/LambdaJS/blob/master/coq/LambdaJS.v&quot;&gt; proof
of soundness in Coq&lt;/a&gt;.&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;What&apos;s Next&lt;/h3&gt;

&lt;p&gt;We&apos;re not done. Here&apos;s what&apos;s coming up:&lt;/p&gt;


&lt;ul&gt;

&lt;li&gt;There are a few easy bits missing from the Coq model (e.g., a parameterized delta-function).&lt;/li&gt;

&lt;li&gt;Once those easy bits are done, we&apos;ll wire it together with desugaring.&lt;/li&gt;


&lt;li&gt;Finally, we&apos;ll upgrade the model to support &lt;a href=&quot;https://blog.brownplt.org/2011/11/11/s5-javascript-semantics.html&quot;&gt; semantics for ECMAScript
5&lt;/a&gt;.&lt;/li&gt;

&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>ECMA Announces Official λJS Adoption</title>
   <link href="http://blog.brownplt.org/2012/04/01/ecma-lambdajs-announcement.html"/>
   <updated>2012-04-01T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2012/04/01/ecma-lambdajs-announcement</id>
   <content type="html">&lt;div style=&quot;font-size: 10pt; font-family: arial&quot;&gt;

&lt;p&gt;&lt;em&gt;GENEVA&lt;/em&gt; -
ECMA&apos;s Technical Committee 39, which oversees the standardization of
ECMAScript, has completed the adoption of Brown PLT&apos;s λ&lt;sub&gt;JS&lt;/sub&gt; as the new
basis for the language. &quot;We were being hampered by the endless
debates about the semantics of ECMAScript 5&quot;, said J. Neumann, the
Chairman of the Committee. &quot;By adopting λ&lt;sub&gt;JS&lt;/sub&gt;, we can return to
focusing on the important parts of the programming language instead,
such as its interaction with parts of the W3C DOM Specification.&quot;
&lt;/p&gt;

&lt;p style=&quot;width: 8em; float:right; font-size:12pt; padding: 1em;
margin: 1em; background-color: #eee; border: 1px solid black;
text-align: left;&quot;&gt;&quot;The replacement of scope objects
with substitution is a clear design flaw.&quot;&lt;br/&gt;-Arjun Guha&lt;/br&gt;&lt;/p&gt;

&lt;p&gt; &lt;b&gt;Improvements to λ&lt;sub&gt;JS&lt;/sub&gt;&lt;/b&gt; - Neumann added that the
standardization process uncovered a significant weakness in
λ&lt;sub&gt;JS&lt;/sub&gt;: the absence of the &lt;code&gt;with&lt;/code&gt; construct. The
Technical Committee therefore mandated its introduction.  Lead designer
Arjun Guha agreed, stating, &quot;The replacement of scope objects with
substitution is a clear design flaw.  It was pointed out to me by
numerous academic researchers who have obtained considerable mileage
from them, but it took me a while to appreciate their value.&quot; The
Committee also recommended a &quot;strict mode&quot;, so Guha removed first-class
functions, which are widely believed to induce laxity by deferring
decision-making.  &lt;/p&gt;

&lt;p&gt; &lt;b&gt;Opposition to the Change&lt;/b&gt; - The adoption of λ&lt;sub&gt;JS&lt;/sub&gt; has
not, however, met with unanimous approval.  When asked for comment,
Douglas Crockford of Yahoo!  complained that the small parts are not
good while the good parts are not small.  Another detractor,
Northeastern University researcher Sam Tobin-Hochstadt, had pushed for
the adoption of Racket as the core language instead of λ&lt;sub&gt;JS&lt;/sub&gt;,
but he admitted that Racket was untenable as it suffered from having a
working module system. The team from Apple declined response, but it is
widely rumored that Jonathan Ive is at work on a new core calculus that
will have only one operation, which will automatically take the step
that the user did not know they should have performed.  &lt;/p&gt;

&lt;p style=&quot;width: 8em; float:left; font-size:12pt; padding: 1em;
margin: 1em; background-color: #eee; border: 1px solid black;
text-align: left;&quot;&gt;&quot;We see this as a fight for the future
of the Internet.&quot;&lt;br/&gt;-David Herman&lt;/br&gt;&lt;/p&gt;

&lt;p&gt; &lt;b&gt;Influential Support&lt;/b&gt; - Nevertheless, the adoption has support
from various influential circles. The Internet Explorer group at
Microsoft has already agreed to implement λ&lt;sub&gt;JS&lt;/sub&gt; in the core
engine of their upcoming release, IE12; lead designer Dean Hachamovitch
said it is second in innovation only to the introduction of tabs. Strict
mode will be supported in IE13.  Google&apos;s Mark Miller pointed out, &quot;With
the aid of membranes, any primordial vat can be instantiated with
desirable liveness properties.&quot; When asked to comment about
λ&lt;sub&gt;JS&lt;/sub&gt; instead of the Miller-Urey experiment, Miller repeated
the comment. Finally, noted Mozilla researcher Dave Herman commented,
&quot;For Mozilla, we see this as a fight for the future of the Internet.&quot; On
questioning, he admitted that he diverts all interviews into
conversations about Boot2Gecko.  &lt;/p&gt;


&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Objects in Scripting Languages</title>
   <link href="http://blog.brownplt.org/2012/02/28/scripting-objects.html"/>
   <updated>2012-02-28T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2012/02/28/scripting-objects</id>
   <content type="html">&lt;p&gt; We&apos;ve been studying scripting languages in some detail, and have
collected a number features of their object systems that we find
unusually expressive.  This expressiveness can be quite powerful, but
also challenges attempts to reason about and understand programs that
use these features.  This post outlines some of these exceptionally
expressive features for those who may not be intimately familiar with
them.  &lt;/p&gt;

&lt;h3&gt;Dictionaries with Inheritance&lt;/h3&gt;

&lt;p&gt;
Untyped scripting languages implement objects as dictionaries mapping
member names (strings) to values.  Inheritance affects member lookup,
but does not affect updates and deletion.  This won&apos;t suprise any
experienced JavaScript programmer:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Using __proto__ sets up inheritance directly in most browsers&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;__proto__&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;// evaluates to 1&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;// evaluates to 9&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// creates new field on obj&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;// evaluates to 50, z on parent is &quot;overridden&quot;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// evaluates to 9; parent.z was unaffected by obj.z = 50&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; In other scripting languages, setting up this inheritance can&apos;t be
done quite so directly.  Still, its effect can be accomplished, and the
similar object structure observed.  For example, in Python:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;                 &lt;span class=&quot;c1&quot;&gt;# class member
&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;# instance member
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;                 &lt;span class=&quot;c1&quot;&gt;# evaluates to 1
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;                 &lt;span class=&quot;c1&quot;&gt;# evaluates to 9
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;# creates new field on obj
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;                 &lt;span class=&quot;c1&quot;&gt;# evaluates to 50, z on parent is &quot;overridden&quot;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;              &lt;span class=&quot;c1&quot;&gt;# evaluates to 9, just like JavaScript &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; We can delete the field in both languages, which returns
&lt;code&gt;obj&lt;/code&gt; to its original state, before it was extended with a
&lt;code&gt;z&lt;/code&gt; member.  In JavaScript: &lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;k&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;               &lt;span class=&quot;c1&quot;&gt;// evaluates to 9 again&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This also works in Python:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;nb&quot;&gt;delattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;z&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;               &lt;span class=&quot;c1&quot;&gt;# evaluates to 9 again&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;
In both languages, we could have performed the assignments and lookups
with computed strings as well:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// JavaScript&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;x &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;yz&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;99&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;// creates a new field, &quot;x yz&quot;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;x y&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;              &lt;span class=&quot;c1&quot;&gt;// evaluates to 99&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Python
&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;setattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;x &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;yz&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# creates a new field, &quot;x yz&quot;
&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;getattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;x y&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;z&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# evaluates to 99&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;
We can go through this entire progression in Ruby, as well:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# returns 1&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# returns 9&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# return 50&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# no simple way to invoke shadowed z method&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remove_method&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# returns 9&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;define_method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;xyz&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to_sym&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;xyz&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# returns 99&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3&gt;Classes Do Not Shape Objects&lt;/h3&gt;

&lt;p&gt; The upshot is that a class definition in a scripting language says
little about the structure of its instances.  This is in contrast to a
language like Java, in which objects&apos; structure is completely determined
by their class, to the point where memory layouts can be predetermined
for runtime objects.  In scripting languages, this isn&apos;t the case.  An
object is an instance of a &apos;class&apos; in JavaScript, Python, or Ruby merely
by virtue of several references to other runtime objects.  Some of these
be changed at runtime, others cannot, but in all cases, members can be
added to and removed from the inheriting objects.  This flexibility can
lead to some unusual situations.  &lt;/p&gt;

&lt;p&gt; &lt;b&gt;Brittle inheritance:&lt;/b&gt; Fluid classes make inheritance brittle.
If we start with this Ruby class: &lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;A&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@privateFld&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;myMethod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@privateFld&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@privateFld&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; Then we might assume that implementation of &lt;code&gt;myMethod&lt;/code&gt; assumes
a numeric type for &lt;code&gt;@privateFld&lt;/code&gt;.  This assumption can be
broken by subclasses, however: &lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;A&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@privateFld&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;string (not num)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;
Since both &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; use the same name, and it
is simply a dictionary key, &lt;code&gt;B&lt;/code&gt; instances violate the
assumptions of &lt;code&gt;A&lt;/code&gt;&apos;s methods:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;myMethod&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# error: cannot multiply strings&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;
Ruby&apos;s authors are well aware of this; &lt;a target=&quot;_blank&quot;
href=&quot;http://books.google.com/books?hl=en&amp;lr=&amp;id=jcUbTcr5XWwC&amp;oi=fnd&amp;pg=PR5&amp;dq=the+ruby+programming+language&amp;ots=fIDgwbarbD&amp;sig=kPP2ZlLrH96wOTjyL7KdrUjsAbg#v=onepage&amp;q=the%20ruby%20programming%20language&amp;f=false&quot;&gt;
the Ruby manual&lt;/a&gt; states &quot;it is only
safe to extend Ruby classes when you are familiar with (and in control
of) the implementation of the superclass&quot; (page 240).
&lt;/p&gt;

&lt;p&gt; &lt;b&gt;Mutable Inheritance:&lt;/b&gt; JavaScript and Python expose the
inheritance chain through mutable object members.  In JavaScript, we
already saw that the member &lt;code&gt;&quot;__proto__&quot;&lt;/code&gt; could be used to
implement inheritance directly.  The &lt;code&gt;&quot;__proto__&quot;&lt;/code&gt; member is
mutable, so class hierarchies can be changed at runtime.  We found it a
bit more surprising when we realized the same was possible in Python:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;from class A&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;from class B&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;# evaluates to &quot;from class A&quot;
&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# evaluates to True
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__class__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# the __class__ member determines inheritance
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;# evaluates to &quot;from class B&quot;
&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# evaluates to True: obj&apos;s &apos;class&apos; has changed!&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3&gt;Methods?&lt;/h3&gt;

&lt;p&gt; These scripting languages also have flexible, and different,
definitions of &quot;methods&quot;.
&lt;/p&gt;

&lt;p&gt;
JavaScript simply does not have methods.  The syntax
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;
Binds &lt;code&gt;this&lt;/code&gt; to the value of &lt;code&gt;obj&lt;/code&gt; in the body of
&lt;code&gt;method&lt;/code&gt;.  However, the &lt;code&gt;method&lt;/code&gt; member is just a
function and can be easily extracted and applied:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;
Since &lt;code&gt;f()&lt;/code&gt; does not use the method call syntax above, it is
treated as a function call.  In this case, it is a well known JavaScript
wart that &lt;code&gt;this&lt;/code&gt; is bound to a default &quot;global object&quot; rather
than &lt;code&gt;obj&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt; Python and Ruby make a greater effort to retain a binding for the
&lt;code&gt;this&lt;/code&gt; parameter.  Python doesn&apos;t care about the name of the
parameter (though &lt;code&gt;self&lt;/code&gt; is canonically used), and simply has
special semantics for the first argument of a method.  If a method is
extracted via member access, it returns a function that binds the object
from the member access to the first parameter:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self_in_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self_in_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myField&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;900&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self_in_method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self_in_method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myField&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;f1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# the access binds self_in_method to obj
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;             &lt;span class=&quot;c1&quot;&gt;# evaluates to 900, using the above binding&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;
If the same method is accessed as a field multiple times, it isn&apos;t the same
function both times―a new function is created for each access:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;f1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# first extraction
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# second extraction
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;f1&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f2&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;# evaluates to False, no reference equality&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;
Python lets programmers access the underlying function without the first
parameter bound through the member &lt;code&gt;im_func&lt;/code&gt;.  This is
actually the same reference across all extracted methods, regardless of
even the original object of extraction:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;f1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# first extraction
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# second extraction
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;otherobj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;f3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# extraction from another object
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# evaluates to True, same function referenced from extractions on the
# same object
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;im_func&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;im_func&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# evaluates to True, same function referenced from extractions on
# different objects
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;im_func&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;im_func&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; Ruby has a similar treatment of methods, their extraction, and their
reapplication to new arguments.&lt;/p&gt;

&lt;h3&gt;But Why?&lt;/h3&gt;

&lt;p&gt; These features aren&apos;t just curiosities―we&apos;ve found examples where
they are used in practice.  For example, Django&apos;s ORM builds classes
dynamically, modifying them based on strings that come from modules
describing database tables and relationships (&lt;a target=&quot;_blank&quot;
href=&quot;https://github.com/django/django/blob/de8cbd29beec8a3b1ef4b8b3cf5aa530883fa350/django/db/models/base.py#L157&quot;&gt;
base.py&lt;/a&gt;):
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;attr_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;%s_ptr&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;module_name&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;field&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OneToOneField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attr_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;auto_created&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent_link&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;new_class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_to_class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attr_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;
Ruby on Rails&apos; ActiveRecord uses dynamic field names as well, iterating
over fields and invoking methods only when their names match certain
patterns (&lt;a target=&quot;_blank&quot;
href=&quot;https://github.com/rails/rails/blob/acf7e86024fa8f7768f02a84688ae6e20c808c9c/activerecord/lib/active_record/attribute_assignment.rb#L78&quot;&gt;
base.rb&lt;/a&gt;):
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;multi_parameter_attributes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;respond_to?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;=&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;is_a?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;nested_parameter_attributes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;=&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;UnkownAttributeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;unknown attribute: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; These applications use objects as dictionaries (with inheritance) to
build up APIs that they couldn&apos;t otherwise.

&lt;p&gt;
These expressive features aren&apos;t
without their perils.  Django has &lt;a target=&quot;_blank&quot;
href=&quot;https://docs.djangoproject.com/en/dev/topics/db/models/#be-careful-with-related-name&quot;&gt;
explicit warnings&lt;/a&gt; that things can go awry if relationships between
tables expressed in ORM classes overlap. And the fact that
&lt;code&gt;__proto__&lt;/code&gt; is in the same namespace as the other members bit
Google Docs, whose &lt;a target=&quot;_blank&quot;
href=&quot;http://groups.google.com/a/googleproductforums.com/forum/#!category-topic/docs/documents/0hQWeOvCcHU&quot;&gt;
editor would crash&lt;/a&gt; if the string &lt;code&gt;&quot;__proto__&quot;&lt;/code&gt; was
entered.  The implementation was using an object as a hashtable keyed by
strings from the document, which led to an assignment to
&lt;code&gt;__proto__&lt;/code&gt; that changed the behavior of the map.
&lt;/p&gt;

&lt;h3&gt;So?&lt;/h3&gt;

&lt;p&gt; The languages presented here are widely adopted and used, and run
critical systems.  Yet, they contain features that defy conventional
formal reasoning, at the very least in their object systems.  Perhaps
these features&apos; expressiveness outweighs the cognitive load of using
them.  If it doesn&apos;t, and using these features is too difficult or
error-prone, we should build tools to help us use them, or find better
ways to implement the same functionality.  And if not, we should take
notice and recall that we have these powerful techniques at our
disposal in the next object system we design.  &lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>S5: Wat?</title>
   <link href="http://blog.brownplt.org/2012/01/31/s5-wat.html"/>
   <updated>2012-01-31T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2012/01/31/s5-wat</id>
   <content type="html">&lt;p&gt;&lt;a target=&quot;_blank&quot;
href=&quot;https://www.destroyallsoftware.com/talks/wat&quot;&gt;Gary Bernhardt&apos;s Wat
talk&lt;/a&gt; has been making a well-deserved round of the blogodome in the
past few weeks.  If you haven&apos;t seen it, go give it a watch (you can
count it as work time, since you saw it on the Brown PLT Blog, and we&apos;re
Serious Researchers).  The upshot of the second half of the talk is that
JavaScript has some less than expected behaviors.  We happen to have a
JavaScript implementation floating around &lt;a
href=&quot;https://blog.brownplt.org/2011/11/11/s5-javascript-semantics.html&quot;&gt;in the form of S5&lt;/a&gt;,
and like to claim that it handles the hairy corners of the language.  We
decided to throw Gary&apos;s examples at it.  &lt;/p&gt;

&lt;h3&gt;The Innocuous +&lt;/h3&gt;

&lt;p&gt;
Gary&apos;s first JavaScript example went like this:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;failbowl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;master&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;jsc&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;kc&quot;&gt;NaN&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt; 

&lt;p&gt; S5 lacks a true REPL―it simply takes JavaScript strings and produces
output and answers―so we started by approximating a little bit.  We
first tried a series of &lt;code&gt;print&lt;/code&gt; statements to see if we got
the same effect: &lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tests&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;arrays&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;js&lt;/span&gt; 
&lt;span class=&quot;nx&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{});&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;s5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tests&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;arrays&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;js&lt;/span&gt; 

&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;WAT.&lt;/p&gt;

&lt;p&gt; Well, that doesn&apos;t seem good at all.  Only half of the answers are
right, and there&apos;s an &lt;code&gt;undefined&lt;/code&gt; at the end. What went
wrong?  It turns out the semantics of REPLs are to blame.  If we take
the four programs and run them on their own, we get something that looks
quite a bit better: &lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;s5&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[] + []&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;dl&quot;&gt;&quot;&quot;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;s5&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[] + {}&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[object Object]&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;s5&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;{} + []&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;s5&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;{} + {}&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;nan&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;
There are two issues here:

&lt;ol&gt;
&lt;li&gt;Why do &lt;code&gt;0.&lt;/code&gt; and &lt;code&gt;nan&lt;/code&gt;
print like that?&lt;/li&gt;
&lt;li&gt;Why did this work, when the previous
attempt didn&apos;t?&lt;/li&gt;
&lt;/ol&gt;

&lt;/p&gt;

&lt;p&gt; The answer to the first question is pretty straightforward:  under
the covers, S5 is using Ocaml floats and printing Ocaml values at the
end of its computation, and Ocaml makes slightly different decisions
than JavaScript in printing numbers.  We could change S5 to print
answers in JavaScript-printing mode, but the values themselves are the
right ones.  &lt;/p&gt;

&lt;p&gt; The second question is more interesting.  Why do we get such
different answers depending on whether we evaluate individual strings
versus printing the expressions?  The answer is in the semantics of
JavaScript REPLs.  When parsing a piece of JavaScript, the REPL needs to
make a choice.  Sensible decisions would be to treat each new JavaScript
string as a &lt;a target=&quot;_blank&quot;
href=&quot;http://es5.github.com/#A.4&quot;&gt;Statement&lt;/a&gt;, or as an entire
JavaScript &lt;a target=&quot;_blank&quot;
href=&quot;http://es5.github.com/#x14&quot;&gt;Program&lt;/a&gt;.  Most REPLs choose the
Program production.  &lt;/p&gt;

&lt;p&gt; The upshot is that the parsing of &lt;code&gt;{} + {}&lt;/code&gt; is quite
different from &lt;code&gt;[] + []&lt;/code&gt;.  With S5, it&apos;s trivial to print the
desugared representation and understand the difference.  When we parse
and desugar, we get very different results for &lt;code&gt;{} + {}&lt;/code&gt; and
&lt;code&gt;[] + []&lt;/code&gt;: &lt;/p&gt;

&lt;pre&gt;
$ ./s5-print &quot;{} + {}&quot;
{undefined;
 &lt;a target=&quot;_blank&quot;
href=&quot;https://github.com/brownplt/LambdaS5/blob/a20d9885ca8277af81029982e5a5c0d903600b31/envs/es5.env#L4613&quot;&gt;%UnaryPlus&lt;/a&gt;({[#proto: %ObjectProto,
              #class: &quot;Object&quot;,
              #extensible: true,]
             })}

$ ./s5-print &quot;[] + []&quot;
&lt;a target=&quot;_blank&quot;
href=&apos;https://github.com/brownplt/LambdaS5/blob/a20d9885ca8277af81029982e5a5c0d903600b31/envs/es5.env#L4057&apos;&gt;%PrimAdd&lt;/a&gt;({
    [#proto: %ArrayProto,
     #class: &quot;Array&quot;,
     #extensible: true,]
    &apos;length&apos; : {#value 0., #writable true, #configurable false}
  },
  {
    [#proto: %ArrayProto,
     #class: &quot;Array&quot;,
     #extensible: true,]
    &apos;length&apos; : {#value 0., #writable true, #configurable false}
  }
)
&lt;/pre&gt;

&lt;p&gt; It is clear that &lt;code&gt;{} + {}&lt;/code&gt; parses as two statements (an
&lt;code&gt;undefined&lt;/code&gt; followed by a &lt;code&gt;UnaryPlus&lt;/code&gt;), and
&lt;code&gt;[] + []&lt;/code&gt; as a single statement containing a binary addition
expression.  What&apos;s happening is that in the Program production, for the
string &lt;code&gt;{} + {}&lt;/code&gt;, the first &lt;code&gt;{}&lt;/code&gt; is matched with
the &lt;a target=&quot;_blank&quot; href=&quot;http://es5.github.com/#x12.1&quot;&gt;Block&lt;/a&gt;
syntactic form, with no internal statements.  The rest of the expression
is parsed as a &lt;a target=&quot;_blank&quot;
href=&quot;http://es5.github.com/#x11.4&quot;&gt;UnaryExpression&lt;/a&gt;.  This is in
contrast to &lt;code&gt;[] + []&lt;/code&gt;, which only correctly parses as an
ExpressionStatement containing an &lt;a target=&quot;_blank&quot;
href=&quot;http://es5.github.com/#x11.6&quot;&gt;AdditiveExpression&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt; In the example where we used successive &lt;code&gt;print&lt;/code&gt;
statements, &lt;em&gt;every&lt;/em&gt; expression in the argument position to print
was parsed in the second way, hence the different answers.  The lesson?
When you&apos;re at a REPL, be it Firebug, Chrome, or the command line, make
sure the expression you&apos;re typing is what you think it is: not being
aware of this difference can make it even more difficult to know what to
expect!  &lt;/p&gt;

&lt;h3&gt;If You Can&apos;t Beat &apos;Em...&lt;/h3&gt;

&lt;p&gt; Our first example led us on an interesting excursion into parsing,
from which S5 emerged triumphant, correctly modelling the richness
and/or weirdness of the addition examples.  Next up, Gary showed some
straightforward uses of &lt;code&gt;Array.join()&lt;/code&gt;: &lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;failbowl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;master&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;jsc&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;,,,,,,,,,,,,,,,,&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;wat&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;watwatwatwatwatwatwatwatwatwatwatwatwatwatwatwat&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;wat&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;wat1wat1wat1wat1wat1wat1wat1wat1wat1wat1wat1wat1wat1wat1wat1wat1&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;wat&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; Batman&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Batman&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; Our results look oh-so-promising, right up until the last line
(note: we call &lt;code&gt;String&lt;/code&gt; on the first case, because S5 doesn&apos;t
automatically &lt;code&gt;toString&lt;/code&gt; answers, which the REPL does).
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;s5&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;String(Array(16))&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;,,,,,,,,,,,,,,,,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;s5&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Array(16).join(&apos;wat&apos;)&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;watwatwatwatwatwatwatwatwatwatwatwatwatwatwatwat&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;s5&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Array(16).join(&apos;wat&apos; + 1)&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;wat1wat1wat1wat1wat1wat1wat1wat1wat1wat1wat1wat1wat1wat1wat1wat1&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;s5&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Array(16).join(&apos;wat&apos; - 1) + &apos; Batman&apos;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull Batman&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;
WAT.
&lt;/p&gt;

&lt;p&gt;
Are we really that awful that we somehow yield &lt;code&gt;null&lt;/code&gt; rather
than &lt;code&gt;NaN&lt;/code&gt;?  A quick glance at the desugared code shows us
that we actually have the &lt;em&gt;constant value&lt;/em&gt; &lt;code&gt;null&lt;/code&gt; as
the argument to &lt;code&gt;join()&lt;/code&gt;.  How did that happen?
Interestingly, the following version of the program works:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;s5&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;var wat = &apos;wat&apos;; Array(16).join(wat - 1) + &apos; Batman&apos;;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN Batman&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; This leads us to our answer.  We use SpiderMonkey&apos;s very handy &lt;a
target=&quot;_blank&quot;
href=&quot;https://developer.mozilla.org/en/SpiderMonkey/Parser_API&quot;&gt;Parser
API&lt;/a&gt; as part of our toolchain. &lt;code&gt;Reflect.parse()&lt;/code&gt; takes
strings and converts them to JSON structures with rich AST information,
which we stringify and pass off to the innards of S5 to do desugaring
and evaluation.  &lt;code&gt;Reflect.parse()&lt;/code&gt; is part of a JavaScript
implementation that strives for performance, and to that end it performs
constant folding.  That is, as an optimization, when it sees the
expression &lt;code&gt;&quot;wat&quot; - 1&lt;/code&gt;, it automatically converts it to
&lt;code&gt;NaN&lt;/code&gt;.  All good so far.  &lt;/p&gt;

&lt;p&gt; The issue is that the &lt;code&gt;NaN&lt;/code&gt; yielded by constant folding
is not quite the same &lt;code&gt;NaN&lt;/code&gt; we might expect in JavaScript
programs.  In JavaScript, the &lt;em&gt;identifier&lt;/em&gt; &lt;code&gt;NaN&lt;/code&gt; is a
property of the global object &lt;a target=&quot;_blank&quot;
href=&quot;http://es5.github.com/#x15.1.1.1&quot;&gt;with the value
&lt;code&gt;NaN&lt;/code&gt;&lt;/a&gt;.  The Parser API can&apos;t safely fold to the
identifier &lt;code&gt;NaN&lt;/code&gt; (as was &lt;a target=&quot;blank&quot;
href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=722087#c1&quot;&gt;pointed
out to us&lt;/a&gt; when we reported this bug), because it might be shadowed
in a different context.  Presumably to avoid this pitfall, the folding
yields a JSON structure that looks like: &lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;expression&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Literal&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;NaN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; But we can&apos;t sensibly use &lt;code&gt;JSON.stringify()&lt;/code&gt; on this
structure, because &lt;code&gt;NaN&lt;/code&gt; isn&apos;t valid JSON!  Any guesses on
what SpiderMonkey&apos;s JSON implementation turns &lt;code&gt;NaN&lt;/code&gt; into?  If
you guessed &lt;code&gt;null&lt;/code&gt;, we owe you a cookie.  &lt;/p&gt;

&lt;p&gt; &lt;span style=&quot;text-decoration: line-through;&quot;&gt; We have designed a
hack based on suggestions from the bug report to get around this
(passing a function to &lt;code&gt;stringify&lt;/code&gt; to look for
&lt;code&gt;NaN&lt;/code&gt;s and return a stylized object literal instead).
There&apos;s a bug open to make constant folding optional in
&lt;code&gt;Reflect.parse()&lt;/code&gt;, so this will be fixed in Mozilla&apos;s
parser.&lt;/span&gt; &lt;span style=&quot;font-weight: bold;&quot;&gt;(Update)&lt;/span&gt; The bug
is fixed, and we&apos;ve updated our version of Spidermonkey.  This example
now works happily, thanks to Dave Herman. &lt;/p&gt;

&lt;p&gt;
Producing a working JavaScript implementation leads to a whole host of
exciting moments and surprising discoveries.  Building this semantics
and its desugaring gives us much more confidence that our tools say
something meaningful about real JavaScript programs.  These examples
show that getting perfect correspondence is difficult, but we strive to
be as close as possible.
&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Belay Lessons: Smarter Web Programming</title>
   <link href="http://blog.brownplt.org/2011/12/18/resume-belay.html"/>
   <updated>2011-12-18T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2011/12/18/resume-belay</id>
   <content type="html">&lt;p&gt;
&lt;em&gt;

This post comes from the keyboard of Matt Carroll, who has worked with us for
the past two years.  He&apos;s the main implementer of desugaring for &lt;a
href=&quot;https://blog.brownplt.org/2011/11/11/s5-javascript-semantics.html&quot;&gt;S5&lt;/a&gt;, and spent this
semester rebuilding and improving in-house Brown PLT web applications.  He
writes about his experience here.

&lt;/em&gt;
&lt;/p&gt;

&lt;p&gt;The Brown computer science department uses a home-grown web application
called Resume to conduct its
faculty recruitment process.  This semester, Joe and I re-wrote Resume with &lt;a
href=&apos;https://sites.google.com/site/belayresearchproject/&apos;&gt;Belay&lt;/a&gt;.  Belay is
the product of Joe and Arjun&apos;s summer research at Google: it&apos;s an ongoing
inquiry into web development best practices, specifically concerning identity,
account management, and security.  From my perspective (that of a novice web
programmer), getting to grips with the Belay philosophy was a thought-provoking
experience, and a great education in the pitfalls that a web developer must
(unfortunately) bear in mind.&lt;/p&gt;

&lt;h3&gt;I Am Not My Cookies&lt;/h3&gt;

&lt;p&gt;Standard web applications make use of cookies for authentication.
When you visit a site and enter your credentials, the site&apos;s response sets a
session cookie in your browser. Subsequent requests to the site use the
information in the cookie to determine &apos;who you are&apos; and whether &apos;you&apos; are
allowed to do what &apos;your&apos; request is trying to do.  I use quotations in the
prior sentence to highlight the fact that HTTP cookies are a poor method of
establishing user identity.  If another, malicious, web site you visit manages
to trick you into sending a request to the original site, that request will
contain your cookie, and the good site may treat that request as legitimate and
execute it.  This is the infamous &lt;a
href=&apos;http://en.wikipedia.org/wiki/Cross-site_request_forgery&apos;&gt;cross-site
request forgery (CSRF)&lt;/a&gt; attack.&lt;/p&gt;

&lt;p&gt;Belay applications eschew the use of cookies, especially for
authentication, and thus they are secure by design against this type of
vulnerability.  This begs the question: without cookies, how do Belay
applications decide whether a request is authenticated?  The answer may shock
you (as it did me):  all requests that reach request handler code are treated
as legitimate.  At this point, we must examine the server-side of Belay apps in
greater detail.&lt;/p&gt;


&lt;h3&gt;Web Capabilities&lt;/h3&gt;

&lt;p&gt;Your everyday possibly-CSRF-vulnerable site probably has a URL scheme with
well-known endpoints that lead directly to application functionality.  For
example, to post to your blog, you (typically via your browser) send a POST
request to &lt;code&gt;www.blog.com/post&lt;/code&gt; with your cookies and the
blog body&apos;s text.  The server-side handler finds your account in the database using
your cookie, checks that your account can post to that blog, and adds a new
post.  If the whole surface of the site&apos;s URL space is well-known, a CSRF-ing
attacker can excercise the entirety of a user&apos;s view of the site with one
compromised cookie.&lt;/p&gt;

&lt;p&gt;In contrast, Belay applications have few well-known URLs, corresponding to
the public entry points to the site (the login and contact pages, for
instance).  Instead, Belay&apos;s libraries allow server-side code to dynamically
generate random unique URLs and map them to request handler functions.  Each of
these handlers services a particular type of request for a particular set of
data.  The randomly generated &quot;capability&quot; urls are embedded in the JavaScript
or markup returned to the browser.  In a well-designed Belay application, each
page has the minimum necessary set of capabilities to carry out its mission,
and the capabilities are scoped to the minimum set of data with which they need
concern themselves.   After you successfully log in to a Belay site, the
response will contain the set of capabilities needed by the page, and scoped to
only that data which is needed by the page&apos;s functionality &lt;em&gt;and&lt;/em&gt;
associated with your user account.  No cookies are necessary to identify you as
a user or to authenticate your requests.&lt;/p&gt;

&lt;p&gt;A Belay app uses its limited URL scheme as its primary security mechanism,
ignoring requests unless they come along trusted capability URLs created by a
prior, explicit grant. As long as we can rely on our platform&apos;s ability to
generate unguessable large random numbers, attackers are out of luck.  And,
even if a capability URL is leaked from its page, it is scoped to only a small
set of data on the server, so the vulnerability is limited.  This is a
much-improved situation compared to a site using cookie-based
authentication---leaking a cookie leaks access to the user&apos;s entire view of the
site.&lt;/p&gt;

&lt;h3&gt;Grants and Cap Handlers&lt;/h3&gt;

&lt;p&gt;Here&apos;s a Belay request handler, taken from Resume:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GetLetterHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bcap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CapHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_letter_filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;letter&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt; 

&lt;p&gt;This handler simply looks up the filename associated with a reference and
returns it (using a few helper functions).  Accessing a letter written by an
applicant&apos;s reference is quite a sensitive operation---letting the wrong
person access a letter would be a serious security bug.  Yet,
&lt;code&gt;GetLetterHandler&lt;/code&gt; is a two-liner with no apparent security checks
or guards.  How can this be safe?
&lt;/p&gt;

&lt;p&gt;To answer this, we need to consider how a client can cause
&lt;code&gt;GetLetterHandler&lt;/code&gt; to be invoked.  The Belay server library will
only invoke this handler via capability URLs created with a &lt;code&gt;grant&lt;/code&gt;
to &lt;code&gt;GetLetterHandler&lt;/code&gt;.  So, we can search the codebase for code
that granted such access.  A quick search shows one spot:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GetApplicantsHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bcap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CapHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reviewer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;applicants_json&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applicant&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reviewer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_applicants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; 
      &lt;span class=&quot;c1&quot;&gt;# ... some processing
&lt;/span&gt;      &lt;span class=&quot;n&quot;&gt;refs_json&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applicants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_references&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;refs_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&apos;refName&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&apos;getLetter&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bcap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetLetterHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# ... add some things to applicants_json
&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bcap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bcapResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;applicants_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; When &lt;code&gt;GetApplicantsHandler&lt;/code&gt; is invoked, it will return a
structure that, for each applicant, shows something like:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Theodore Roosevelt&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;getLetter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;https://resume.cs.brown.edu/cap/f7327056-4b91-ad57-e5e4f6c514b6&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; On the server, the string
&lt;code&gt;f7327056-4b91-ad57-e5e4f6c514b6&lt;/code&gt; was created and mapped to
the pair of &lt;code&gt;GetLetterHandler&lt;/code&gt; and the &lt;code&gt;Reference&lt;/code&gt;
database item for Theodore Roosevelt.  A GET request to the URL above will
return the reference letter.  Note a nice feature of this setup: the server
doesn&apos;t use any information from the client, other than the capability URL, to
decide &lt;em&gt;which&lt;/em&gt; reference&apos;s letter to return.  Thus, a client cannot try
providing different id&apos;s or other parameters to explore which letters they
have access to.  Only those explicitly granted are accessible.  &lt;/p&gt;

&lt;p&gt; Poking around in the codebase more, we can see that
&lt;code&gt;GetApplicantsHandler&lt;/code&gt; is only granted to reviewers, who can only
create accounts via an email from the administrator.  This reasoning is how we
convince ourselves, as developers, that we haven&apos;t screwed up and given away
the ability to see a letter to the wrong user.  We do all of this without
worrying about a check on accessing the letter, instead relying on the
unguessability of the URLs generated by &lt;code&gt;grant&lt;/code&gt; to enforce our
access restrictions.  &lt;/p&gt;

&lt;p&gt;This may seem like a new-concept overload, and indeed, I had that exact
reaction at first.  Over time I gained familiarity with the Belay style, and I
became more and more convinced by the benefits it offers.  Porting Resume
became a fairly straightforward process of identifying each server-side request
handler, converting it to a Belay handler, and ensuring that whatever pages
needed that functionality received grants to call the handler.  There were
wrinkles, many due to the fact that Resume also uses &lt;a
href=&apos;http://www.flapjax-lang.org/&apos;&gt;Flapjax&lt;/a&gt; (a language/library for
reactive programming in the browser).  Flapjax is another Brown PLT product and
it is certainly worthy of its own blog post.  We had to account for the
interaction between Belay&apos;s client-side library and Flapjax.&lt;/p&gt;

&lt;p&gt;  Note that Belay isn&apos;t the first place these ideas have surfaced.  Belay
builds on foundational research:  &lt;a
href=&apos;http://waterken.sourceforge.net/&apos;&gt;Waterken&lt;/a&gt; and &lt;a
href=&apos;http://cs.brown.edu/~sk/Publications/Papers/Published/khmgpf-impl-use-plt-web-server-journal/&apos;&gt;PLT
Web Server&lt;/a&gt; both support cookie-less, capability-based web interactions.
The Belay project addresses broader goals in identity management and sharing
on the web, but we&apos;ve leveraged its libraries to build a more robust system
for ourselves.

&lt;p&gt;At the end, the benefits of the redesigned Resume are numerous.  Cookies are
no longer involved.  JavaScript code doesn&apos;t know or care about unique IDs for
picking items out of the database.  Random HTTP request probes result in a 404
response and a line in the server&apos;s log, instead of a possible data corruption.
You can open as many tabs as you like, with each one logged into its own Resume
account, and experience no unwanted interference.  We were able to realize
these improvements while re-using a significant portion of the original Resume
code, unchanged.&lt;/p&gt;

&lt;p&gt;After my experience with the Resume port, I&apos;m certainly a Belay fan. The
project has more to say about topics such as cross-site authorization, sharing,
and multi-site identity management, so check out their site and stay tuned for
future updates:&lt;/p&gt;

&lt;a href=&apos;https://sites.google.com/site/belayresearchproject/&apos;&gt;Belay
Research&lt;/a&gt;

</content>
 </entry>
 
 <entry>
   <title>S5: Semantics for Accessors</title>
   <link href="http://blog.brownplt.org/2011/12/11/getters-and-setters.html"/>
   <updated>2011-12-11T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2011/12/11/getters-and-setters</id>
   <content type="html">&lt;style&gt;
.semantic {
  font-family: DejaVu Sans;
  font-size: small;
}
&lt;/style&gt;

&lt;p&gt; Getters and setters (known as accessors) are a new feature in ECMAScript 5
that extend the behavior of assignment and lookup expressions on JavaScript
objects.  If a field has a &lt;em&gt;getter&lt;/em&gt; defined on it, rather than simply
returning the value in field lookup, a getter function is invoked, and its
return value is the result of the lookup:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;timesGotten&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;timesGotten&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}};&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;// calls the function above, evaluates to 22&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;timesGotten&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// is now 1, due to the increment in the getter&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;// calls the function above, still evaluates to 22&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;timesGotten&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// is now 2, due to another increment in the getter&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;
Similarly, if a field has a &lt;em&gt;setter&lt;/em&gt; defined on it, the setter
function is called on field update.  The setter function gets the assigned
value as its only argument, and its return value is ignored:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}};&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;37&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// calls the function above (with v=37)&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// evaluates to 37&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// evaluates to undefined&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; Getters and setters have a number of proposed uses―they can be used to wrap
DOM objects that have interesting effects on assignment, like
&lt;code&gt;onmessage&lt;/code&gt; and &lt;code&gt;onbeforeunload&lt;/code&gt;, for example.  We leave
discovering good uses to more creative JavaScript programmers, and focus on
their semantic properties here.  &lt;/p&gt;

&lt;p&gt; The examples above are straightforward, and it seems like a simple model
might work out quite easily.  First, we need some definitions, so we&apos;ll start
with what&apos;s in λ&lt;sub&gt;JS&lt;/sub&gt;.  Here&apos;s a fragment of the values that
λ&lt;sub&gt;JS&lt;/sub&gt; works with, and the most basic of the operations on objects:

&lt;pre style=&apos;font-family:DejaVu Sans;&apos;&gt;
v := str  | { str&lt;sub&gt;1&lt;/sub&gt;:v&lt;sub&gt;1&lt;/sub&gt;, ⋯, str&lt;sub&gt;n&lt;/sub&gt;:v&lt;sub&gt;n&lt;/sub&gt; } | func(x ⋯) . e | ⋯
e := e[e] | e[e=e] | e(e, ⋯) | ⋯

(E-Lookup)
  { ⋯, str:v, ⋯ }[str&lt;sub&gt;x&lt;/sub&gt;] → v
  when str&lt;sub&gt;x&lt;/sub&gt; = str

(E-Update)
  { ⋯, str:v, ⋯}[str&lt;sub&gt;x&lt;/sub&gt;=v&apos;] → { ⋯, str:v&apos;, ⋯}
  when str&lt;sub&gt;x&lt;/sub&gt; = str

(E-UpdateAdd)
  { str&lt;sub&gt;1&lt;/sub&gt;:v&lt;sub&gt;1&lt;/sub&gt;, ⋯}[str=v] → { str:v, str&lt;sub&gt;1&lt;/sub&gt;:v&lt;sub&gt;1&lt;/sub&gt;, ⋯}
  when str ≠ str&lt;sub&gt;1&lt;/sub&gt;, ⋯
&lt;/pre&gt;

&lt;p&gt; We update and set fields when they are found, and add fields if there is an
update on a not-found field.  Clearly, this isn&apos;t enough to model the semantics
of getters and setters.  On lookup, if the value of a field is a getter, we
need to have our semantics step to an invocation of the function.  We need to
make the notion of a field richer, so the semantics can have behavior that
depends on the kind of field.  We distinguish two kinds of fields &lt;span
class=&apos;semantic&apos;&gt;p&lt;/span&gt;, one for simple values and one for
accessors: &lt;/p&gt;

&lt;pre class=&apos;semantic&apos;&gt;
&lt;b&gt;p := [get: v&lt;sub&gt;g&lt;/sub&gt;, set: v&lt;sub&gt;s&lt;/sub&gt;] | [value: v]&lt;/b&gt;
v := str  | { str&lt;sub&gt;1&lt;/sub&gt;:&lt;b&gt;p&lt;sub&gt;1&lt;/sub&gt;&lt;/b&gt;, ⋯, str&lt;sub&gt;n&lt;/sub&gt;:&lt;b&gt;p&lt;sub&gt;n&lt;/sub&gt;&lt;/b&gt; } | func(x ⋯) . e | ⋯
e := e[e] | e[e=e] | e(e, ⋯) | ⋯
&lt;/pre&gt;

&lt;p&gt;
The updated rules for simple values are trivial to write down (differences in bold):
&lt;/p&gt;

&lt;pre class=&apos;semantic&apos;&gt;
(E-Lookup)
  { ⋯, str:&lt;b&gt;[value:v]&lt;/b&gt;, ⋯ }[str&lt;sub&gt;x&lt;/sub&gt;] → v
  when str&lt;sub&gt;x&lt;/sub&gt; = str

(E-Update)
  { ⋯, str:&lt;b&gt;[value:v]&lt;/b&gt;, ⋯}[str&lt;sub&gt;x&lt;/sub&gt;=v&apos;] → { ⋯, str:&lt;b&gt;[value:v&apos;]&lt;/b&gt;, ⋯}
  when str&lt;sub&gt;x&lt;/sub&gt; = str

(E-UpdateAdd)
  { str&lt;sub&gt;1&lt;/sub&gt;:v&lt;sub&gt;1&lt;/sub&gt;, ⋯}[str=v] → { str:&lt;b&gt;[value:v]&lt;/b&gt;, str&lt;sub&gt;1&lt;/sub&gt;:v&lt;sub&gt;1&lt;/sub&gt;, ⋯}
  when str ≠ str&lt;sub&gt;1&lt;/sub&gt;, ⋯
&lt;/pre&gt;

&lt;p&gt;
But now we can also handle the cases where we have a getter or setter.  If a
lookup expression &lt;span class=&apos;semantic&apos;&gt;e[e]&lt;/span&gt; finds a getter, it applies
the function, and the same goes for setters, which get the value as an argument:
&lt;/p&gt;

&lt;pre class=&apos;semantic&apos;&gt;
(E-LookupGetter)
  { ⋯, str:&lt;b&gt;[get:v&lt;sub&gt;g&lt;/sub&gt;, set:v&lt;sub&gt;s&lt;/sub&gt;]&lt;/b&gt;, ⋯ }[str&lt;sub&gt;x&lt;/sub&gt;] → &lt;b&gt;v&lt;sub&gt;g&lt;/sub&gt;()&lt;/b&gt;
  when str&lt;sub&gt;x&lt;/sub&gt; = str

(E-UpdateSetter)
  { ⋯, str:&lt;b&gt;[get:v&lt;sub&gt;g&lt;/sub&gt;, set:v&lt;sub&gt;s&lt;/sub&gt;]&lt;/b&gt;, ⋯}[str&lt;sub&gt;x&lt;/sub&gt;=v&apos;] → &lt;b&gt;v&lt;sub&gt;s&lt;/sub&gt;(v&apos;)&lt;/b&gt;
  when str&lt;sub&gt;x&lt;/sub&gt; = str
&lt;/pre&gt;

&lt;p&gt;
Great!  This can handle the two examples from the
beginning of the post.  But those two examples weren&apos;t the whole story for
getters and setters, and our first fragment wasn&apos;t the whole story for
λ&lt;sub&gt;JS&lt;/sub&gt; objects.
&lt;/p&gt;

&lt;p&gt;
Consider this program:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// calls the set function above (with v=5)&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// evaluates to 10, because of assignment in the setter&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// evaluates to 11, because of addition in the getter&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;
Here, we see that the functions also have access to the target object of the
assignment or lookup, via the &lt;code&gt;this&lt;/code&gt; parameter.  We could try to
encode this into our rules, but let&apos;s not get too far ahead of ourselves.
JavaScript objects have more subtleties up their sleeves.  We can&apos;t forget
about prototype inheritance.  Let&apos;s start with the same object &lt;code&gt;o&lt;/code&gt;,
this time called &lt;code&gt;parent&lt;/code&gt;, and use it as the prototype of another
object:
&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;child&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Sets... what exactly to 10?&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// ??? &lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// ??? &lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// ??? &lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// ??? &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; Take a minute to guess what you think each of the values should be.  &lt;a
id=&apos;showanswers&apos; href=&quot;javascript://Answers&quot;&gt;Click here&lt;/a&gt; to see the answers
(which hopefully are what you expected).  &lt;/p&gt;

&lt;script&gt;
document.getElementById(&apos;showanswers&apos;).addEventListener(&apos;click&apos;, function() {
  document.getElementById(&apos;answers&apos;).style.display = &apos;block&apos;;
});  
&lt;/script&gt;

&lt;div style=&apos;height:11em;padding:0;margin:0;&apos;&gt;
&lt;div id=&apos;answers&apos; style=&apos;display:none;&apos;&gt;
&lt;p&gt;(Update: These answers were changed
on June 20, 2012 when we noticed a bug.  &lt;code&gt;parent.x&lt;/code&gt; used to have
&lt;code&gt;undefined&lt;/code&gt; listed as the answer, which is incorrect.)&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;  &lt;span class=&quot;nx&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// undefined&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// 10&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// NaN (parent._x is undefined, undefined + 1 = NaN)&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// 11&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt; So, JavaScript is passing the object &lt;em&gt;in the lookup expression&lt;/em&gt; into
the function, for both field access and field update.  Something else subtle is
going on, as well.  Recall that before, when an update occurred on a field that
wasn&apos;t present, JavaScript simply added it to the object.  Now, on field
update, we see that the assignment traverses the prototype chain to check for
setters.  This is fundamentally different from JavaScript before
accessors―assignment never considered prototypes.  So, our semantics needs to
do two things: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pass the correct &lt;code&gt;this&lt;/code&gt; argument to getters and setters;&lt;/li&gt;
&lt;li&gt;Traverse the prototype chain for assignments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Let&apos;s think about a simple way to pass the &lt;code&gt;this&lt;/code&gt; argument to
getters:
&lt;/p&gt;

&lt;pre class=&apos;semantic&apos;&gt;
(E-LookupGetter)
  { ⋯, str:[get:v&lt;sub&gt;g&lt;/sub&gt;, set:v&lt;sub&gt;s&lt;/sub&gt;], ⋯ }[str&lt;sub&gt;x&lt;/sub&gt;] → v&lt;sub&gt;g&lt;/sub&gt;(&lt;b&gt;{ ⋯, str:[get:v&lt;sub&gt;g&lt;/sub&gt;, set:v&lt;sub&gt;s&lt;/sub&gt;], ⋯ }&lt;/b&gt;)
  when str&lt;sub&gt;x&lt;/sub&gt; = str
&lt;/pre&gt;

&lt;p&gt; Here, we simply copy the object over into the first argument to the
function &lt;span class=&apos;semantic&apos;&gt;v&lt;sub&gt;g&lt;/sub&gt;&lt;/span&gt;.  We can (and do) desugar
functions to have an implicit first &lt;code&gt;this&lt;/code&gt; argument to line up with
this invocation.  But we need to think carefully about this rule&apos;s interaction
with prototype inheritance.  &lt;/p&gt;

&lt;p&gt;
Here is &lt;span class=&apos;semantic&apos;&gt;E-Lookup-Proto&lt;/span&gt; from the original
λ&lt;sub&gt;JS&lt;/sub&gt;:

&lt;/p&gt;
&lt;pre class=&apos;semantic&apos;&gt;
(E-Lookup-Proto)
  { str&lt;sub&gt;1&lt;/sub&gt;:v&lt;sub&gt;1&lt;/sub&gt;, ⋯, &quot;__proto__&quot;: v&lt;sub&gt;p&lt;/sub&gt;, str&lt;sub&gt;n&lt;/sub&gt;:v&lt;sub&gt;n&lt;/sub&gt;, ⋯}[str] → v&lt;sub&gt;p&lt;/sub&gt;[str]
  when str ≠ str&lt;sub&gt;1&lt;/sub&gt;, ⋯, str&lt;sub&gt;n&lt;/sub&gt;, ⋯
&lt;/pre&gt;

&lt;p&gt; Let&apos;s take a moment to look at this rule in conjunction with &lt;span
class=&apos;semantic&apos;&gt;E-LookupGetter&lt;/span&gt;.  If the field isn&apos;t found, and
__proto__ is present, it looks up the __proto__ field and performs the same
lookup on that object (we are eliding the case where proto is not present or
not an object for this presentation).  But note something crucial: the
expression on the right hand side drops &lt;em&gt;everything&lt;/em&gt; about the original
object except its prototype.  If we applied this rule to &lt;code&gt;child&lt;/code&gt;
above, the getter rule would pass &lt;code&gt;parent&lt;/code&gt; to the getter instead of
&lt;code&gt;child&lt;/code&gt;!  &lt;/p&gt;

&lt;p&gt;  The solution is to keep track of the original object as we traverse the
prototype chain.  If we don&apos;t, the reduction relation simply won&apos;t have the
information it needs to pass in to the getter or setter when it reaches the
right point in the chain.  This is a deep change―we need to modify our
expressions to get it right:&lt;/p&gt;

&lt;style&gt;
.new-outlined {
  font-weight: bold;
  border: 1px solid red;
}
&lt;/style&gt;

&lt;pre class=&apos;semantic&apos;&gt;
p := [get: v&lt;sub&gt;g&lt;/sub&gt;, set: v&lt;sub&gt;s&lt;/sub&gt;] | [value: v]
v := str  | { str&lt;sub&gt;1&lt;/sub&gt;:p&lt;sub&gt;1&lt;/sub&gt;, ⋯, str&lt;sub&gt;n&lt;/sub&gt;:p&lt;sub&gt;n&lt;/sub&gt; } | func(x ⋯) . e | ⋯
e := e[e] | e[e=e] | e&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;/sup&gt;[e] | e&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;/sup&gt;[e=e] | e(e, ⋯) | ⋯
&lt;/pre&gt;

&lt;p&gt; And now, when we do a prototype lookup, we can keep track of the same
&lt;code&gt;this&lt;/code&gt; argument (written as &lt;span class=&apos;semantic&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/span&gt;)
the whole way up the chain, and the rules for getters and setters can use this
new piece of the expression: &lt;/p&gt;

&lt;pre class=&apos;semantic&apos;&gt;
(E-Lookup-Proto)
  { str&lt;sub&gt;1&lt;/sub&gt;:v&lt;sub&gt;1&lt;/sub&gt;, ⋯, &quot;__proto__&quot;: v&lt;sub&gt;p&lt;/sub&gt;, str&lt;sub&gt;n&lt;/sub&gt;:v&lt;sub&gt;n&lt;/sub&gt;, ⋯}&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/sup&gt;[str] → v&lt;sub&gt;p&lt;/sub&gt;&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/sup&gt;[str]
  when str ≠ str&lt;sub&gt;1&lt;/sub&gt;, ⋯, str&lt;sub&gt;n&lt;/sub&gt;, ⋯

(E-LookupGetter)
  { ⋯, str:[get:v&lt;sub&gt;g&lt;/sub&gt;, set:v&lt;sub&gt;s&lt;/sub&gt;], ⋯ }&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/sup&gt;[str&lt;sub&gt;x&lt;/sub&gt;] → v&lt;sub&gt;g&lt;/sub&gt;(&lt;span class=&apos;new-outlined&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/span&gt;)
  when str&lt;sub&gt;x&lt;/sub&gt; = str

(E-UpdateSetter)
  { ⋯, str:[get:v&lt;sub&gt;g&lt;/sub&gt;, set:v&lt;sub&gt;s&lt;/sub&gt;], ⋯}&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/sup&gt;[str&lt;sub&gt;x&lt;/sub&gt;=v&apos;] → v&lt;sub&gt;s&lt;/sub&gt;(&lt;span class=&apos;new-outlined&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/span&gt;,v&apos;)
  when str&lt;sub&gt;x&lt;/sub&gt; = str
&lt;/pre&gt;

&lt;p&gt; This idea was inspired by Di Gianantonio, Honsell, and Liquori&apos;s 1998 &lt;a
href=&apos;http://dl.acm.org/citation.cfm?id=286955&apos;&gt;paper&lt;/a&gt;, &lt;em&gt;A lambda
calculus of objects with self-inflicted extension&lt;/em&gt;.  They use a similar
encoding to model method dispatches in a small prototype-based object calculus.
The original expressions, &lt;span class=&apos;semantic&apos;&gt;e[e]&lt;/span&gt; and &lt;span
class=&apos;semantic&apos;&gt;e[e=e]&lt;/span&gt;, simply copy values into the new positions once
the subexpressions have reduced to values: &lt;/p&gt;

&lt;pre class=&apos;semantic&apos;&gt;
(E-Lookup)
  v[str] → v&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;/sup&gt;[str]

(E-Update)
  v[str=v&apos;] → v&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;/sup&gt;[str=v&apos;]
&lt;/pre&gt;

&lt;p&gt;
The final set of evaluation rules and expressions is a little larger:
&lt;/p&gt;

&lt;pre class=&apos;semantic&apos;&gt;
p := [get: v&lt;sub&gt;g&lt;/sub&gt;, set: v&lt;sub&gt;s&lt;/sub&gt;] | [value: v]
v := str  | { str&lt;sub&gt;1&lt;/sub&gt;:p&lt;sub&gt;1&lt;/sub&gt;, ⋯, str&lt;sub&gt;n&lt;/sub&gt;:p&lt;sub&gt;n&lt;/sub&gt; } | func(x ⋯) . e | ⋯
e := e[e] | e[e=e] | e&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;/sup&gt;[e] | e&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;/sup&gt;[e=e] | e(e, ⋯) | ⋯

(E-Lookup)
  v[str] → v&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;/sup&gt;[str]

(E-Update)
  v[str=v&apos;] → v&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;/sup&gt;[str=v&apos;]

(E-LookupGetter)
  { ⋯, str:[get:v&lt;sub&gt;g&lt;/sub&gt;, set:v&lt;sub&gt;s&lt;/sub&gt;], ⋯ }&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/sup&gt;[str&lt;sub&gt;x&lt;/sub&gt;] → v&lt;sub&gt;g&lt;/sub&gt;(&lt;span class=&apos;new-outlined&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/span&gt;)
  when str&lt;sub&gt;x&lt;/sub&gt; = str

(E-Lookup-Proto)
  { str&lt;sub&gt;1&lt;/sub&gt;:v&lt;sub&gt;1&lt;/sub&gt;, ⋯, &quot;__proto__&quot;: v&lt;sub&gt;p&lt;/sub&gt;, str&lt;sub&gt;n&lt;/sub&gt;:v&lt;sub&gt;n&lt;/sub&gt;, ⋯}&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/sup&gt;[str] → v&lt;sub&gt;p&lt;/sub&gt;&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/sup&gt;[str]
  when str ≠ str&lt;sub&gt;1&lt;/sub&gt;, ⋯, str&lt;sub&gt;n&lt;/sub&gt;, ⋯

(E-UpdateSetter)
  { ⋯, str:[get:v&lt;sub&gt;g&lt;/sub&gt;, set:v&lt;sub&gt;s&lt;/sub&gt;], ⋯}&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/sup&gt;[str&lt;sub&gt;x&lt;/sub&gt;=v&apos;] → v&lt;sub&gt;s&lt;/sub&gt;(&lt;span class=&apos;new-outlined&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/span&gt;,v&apos;)
  when str&lt;sub&gt;x&lt;/sub&gt; = str

(E-Update-Proto)
  { str&lt;sub&gt;1&lt;/sub&gt;:v&lt;sub&gt;1&lt;/sub&gt;, ⋯, &quot;__proto__&quot;: v&lt;sub&gt;p&lt;/sub&gt;, str&lt;sub&gt;n&lt;/sub&gt;:v&lt;sub&gt;n&lt;/sub&gt;, ⋯}&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/sup&gt;[str=v&apos;] → v&lt;sub&gt;p&lt;/sub&gt;&lt;sup class=&apos;new-outlined&apos;&gt;v&lt;sub&gt;t&lt;/sub&gt;&lt;/sup&gt;[str=v&apos;]
  when str ≠ str&lt;sub&gt;1&lt;/sub&gt;, ⋯, str&lt;sub&gt;n&lt;/sub&gt;, ⋯
&lt;/pre&gt;

&lt;p&gt; This is most of the rules―we&apos;ve elided some details to only present the
key insight behind the new ones.  Our full semantics (discussed in our &lt;a
href=&apos;https://blog.brownplt.org/2011/11/11/s5-javascript-semantics.html&apos;&gt;last post&lt;/a&gt;), handles the
details of the &lt;code&gt;arguments&lt;/code&gt; object that is implicitly available
within getters and setters, and using built-ins, like
&lt;code&gt;defineProperty&lt;/code&gt;, to add already-defined functions to existing
objects as getters and setters.  &lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>S5: A Semantics for Today's JavaScript</title>
   <link href="http://blog.brownplt.org/2011/11/11/s5-javascript-semantics.html"/>
   <updated>2011-11-11T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2011/11/11/s5-javascript-semantics</id>
   <content type="html">&lt;p&gt; The JavaScript language isn&apos;t static―the ECMAScript committee is working
hard to improve the language, and browsers are implementing features both in
and outside the spec, making it difficult to understand just what &quot;JavaScript&quot;
means at any point in time.  Existing implementations aren&apos;t much help―their
goal is to serve pages well and fast.  We need a JavaScript architecture that
can help us make sense of the upcoming (and existing!) features of the
language.  &lt;/p&gt;

&lt;p&gt; To this end, we&apos;ve developed &lt;a
href=&quot;http://www.github.com/brownplt/LambdaS5&quot;&gt;S5&lt;/a&gt;, an ECMAScript 5
runtime, built on λ&lt;sub&gt;JS&lt;/sub&gt;, with the explicit goal of helping people
understand and tinker with the language.  We built it to understand the
features in the new standard, building on our &lt;a
href=&quot;http://brownplt.github.com/2011/09/29/js-essence.html&quot;&gt;previous
efforts&lt;/a&gt; for the older standard.  We&apos;ve now begun building analyses for this
semantics, and are learning more about it as we do so.  We&apos;re making it
available with the hope that you can join us in playing with ES5,
extending it with new features, and building tools for it.&lt;/p&gt;

&lt;p&gt; S5 implements the core features of ES5 strict mode.  How do we know
this?  We&apos;ve tested S5 against &lt;a
href=&quot;http://test262.ecmascript.org/&quot;&gt;Test262&lt;/a&gt; to measure our progress.  We
are, of course, not feature complete, but we&apos;re happy with our progress, which
you can check out &lt;a
href=&quot;http://www.cs.brown.edu/~joe/public/s5-tests/summary.html&quot;&gt;here&lt;/a&gt;.


&lt;h3&gt; A Malleable Implementation &lt;/h3&gt;

&lt;p&gt; The semantics of S5 is designed to be two things: a language for writing
down the algorithms of the specification, and a translation target for
JavaScript programs.  We&apos;ve implemented an &lt;a
href=&apos;https://github.com/brownplt/LambdaS5/blob/a20d9885ca8277af81029982e5a5c0d903600b31/src/ljs/ljs_eval.ml&apos;&gt;interpreter&lt;/a&gt;
for S5, and a &lt;a
href=&quot;https://github.com/brownplt/LambdaS5/blob/a20d9885ca8277af81029982e5a5c0d903600b31/src/exprjs/exprjs_to_ljs.ml&quot;&gt;&lt;em&gt;desugaring function&lt;/em&gt;&lt;/a&gt;
that translates JavaScript source into S5 programs.&lt;/p&gt;

&lt;p&gt; We have a number of choices to make in defining desugaring.  The ECMAScript
standard defines a whole host of auxiliary functions and library routines that
we must model.  Putting these implementations directly in the desugaring
function would work, but would make desugaring unnecessary brittle, and require
recompilation on every minor change.  Instead, we implement the bulk of this
functionality as an S5 program.  The majority of our work happens in &lt;a
href=&quot;https://github.com/brownplt/LambdaS5/blob/a20d9885ca8277af81029982e5a5c0d903600b31/envs/es5.env&quot;&gt;an
environment file&lt;/a&gt; that defines the spec in S5 itself.  The desugaring
defines a translation from the syntactic forms of JavaScript to the (smaller)
language of S5, filled with calls into the functions defined in this
environment.&lt;/p&gt;

&lt;p&gt; This separation of concerns is what makes our implementation so amenable to
exploration.  If you want to try something out, you can edit the environment
file and rerun whatever tests you care to learn about.  Want to try a different
implementation of the &lt;code&gt;==&lt;/code&gt; operator?  Just change the definition, as
it was pulled from the spec, at &lt;a
href=&quot;https://github.com/brownplt/LambdaS5/blob/a20d9885ca8277af81029982e5a5c0d903600b31/envs/es5.env#L300&quot;&gt;line
300&lt;/a&gt;.  Want a more expressive &lt;code&gt;Object.toString()&lt;/code&gt; that doesn&apos;t
just print &lt;code&gt;&quot;[object Object]&quot;&lt;/code&gt;?  That&apos;s &lt;a
href=&quot;https://github.com/brownplt/LambdaS5/blob/a20d9885ca8277af81029982e5a5c0d903600b31/envs/es5.env#L990&quot;&gt;right
here&lt;/a&gt;.  No changing an interpreter, no recompiling a desugaring function
necessary.  &lt;/p&gt;

&lt;p&gt; The environment we&apos;ve written reflects the standard&apos;s algorithms as we
understand them in terms of S5.  The desugaring from JavaScript to S5 code with
calls into this library is informed by the specification&apos;s definitions of
expression and statement evaluation.  We have confidence in the combination of
desugaring and library implementation, given our increasing test coverage.
Further, we know how to continue―implement more of the spec and pass more test
cases!  &lt;/p&gt;


&lt;h3&gt; More than λ&lt;sub&gt;JS&lt;/sub&gt; &lt;/h3&gt;

&lt;p&gt; S5 is built on λ&lt;sub&gt;JS&lt;/sub&gt;, but extends it in three significant ways:

&lt;ul&gt;
&lt;li&gt; Explicit getters and setters; &lt;/li&gt;
&lt;li&gt; Object fields with attributes, like &lt;code&gt;writable&lt;/code&gt; and &lt;code&gt;configurable&lt;/code&gt;, built-in; &lt;/li&gt;
&lt;li&gt; Support for &lt;code&gt;eval().&lt;/code&gt;
&lt;/ul&gt;

For those that haven&apos;t fiddled with getters and setters, they are a new feature
introduced in ECMAScript 5 that allow programmer-defined behavior on property
access and assignment.  Getters and setters fundamentally change how property
access and assignment work.  They make property assignment interact with the
prototype chain, which used to not be the case, and cause syntactically similar
expressions to behave quite differently at runtime.  In a separate post we&apos;ll
discuss the interesting problems they introduce for desugaring and how we
implement them in the semantics. (&lt;b&gt;Update&lt;/b&gt;: This post has been written,
&lt;a href=&apos;https://blog.brownplt.org/2011/12/11/getters-and-setters.html&apos;&gt;check it out&lt;/a&gt;!)

&lt;/p&gt;

&lt;p&gt; Attributes on objects weren&apos;t treated directly in the original
λ&lt;sub&gt;JS&lt;/sub&gt;.
In 5th Edition, they are crucial to several security-relevant operations on
objects. For example, the standard specifies &lt;code&gt;Object.freeze()&lt;/code&gt;,
which makes an object&apos;s properties forever unwritable.  S5 directly models the
&lt;code&gt;writable&lt;/code&gt; and &lt;code&gt;configurable&lt;/code&gt; attributes that make this
operation possible, and make its implementation in S5 easy to understand.
&lt;/p&gt;

&lt;p&gt;

λ&lt;sub&gt;JS&lt;/sub&gt; explicitly elided &lt;code&gt;eval()&lt;/code&gt; from its semantics.  S5
implements &lt;code&gt;eval()&lt;/code&gt; by performing desugaring &lt;em&gt;within the
interpreter&lt;/em&gt; and then interpreting the desugared code.  We implement only
the strict mode version of &lt;code&gt;eval&lt;/code&gt;, which restricts the environment
that the &lt;code&gt;eval&lt;/code&gt;&apos;d code can affect.  With these restrictions, we can
implement &lt;code&gt;eval&lt;/code&gt; in a straightforward way within our interpreter.
We&apos;ll cover the details of how we do this, and why it works, in another post.

&lt;/p&gt;


&lt;h3&gt;Building on S5&lt;/h3&gt;

There&apos;s a ton we can do with S5.  More, in fact, than we can do by ourselves:

&lt;ul&gt;


&lt;li&gt;

&lt;b&gt;Experiment with Harmony features&lt;/b&gt;:  ECMAScript 6, or Harmony, as it is
often called, is being designed &lt;em&gt;right now&lt;/em&gt;.  Proxies, string
interpolation, syntactic sugar for classes, and modules are just a few of the
upcoming features.  Modeling them in S5 would help us understand these
features better as they get integrated into the language.

&lt;/li&gt;
&lt;li&gt;

&lt;b&gt;Build Verification Tools&lt;/b&gt;:  Verification based on objects&apos; attributes is an
interesting research problem―what can we prove about interacting programs if
we know about unwritable fields and inextensible objects?  Building this
knowledge into a type-checker or a program analysis could give interesting new
guarantees.

&lt;/li&gt;
&lt;li&gt;

&lt;b&gt;Abstract Our Machine&lt;/b&gt;:  Matt Might and David van Horn wrote about
abstracting λ&lt;sub&gt;JS&lt;/sub&gt; for program analysis.  We&apos;ve added new constructs
to the language since then.  Do they make abstraction any harder?

&lt;/li&gt;

&lt;li&gt;

&lt;b&gt;Complete the Implementation&lt;/b&gt;: We&apos;ve made a lot of progress, but there&apos;s
still more ground to cover.  We need support for more language features,
like JSON and regular expressions, that would move our implementation along
immensely.  We&apos;ll work on this more, but anyone who wants to get involved is
welcome to help.

&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
If any of this sounds interesting, or if you&apos;re just curious, go ahead and
check out S5!  It&apos;s open source and lives in a &lt;a
href=&quot;https://github.com/brownplt/LambdaS5&quot;&gt;Github repository&lt;/a&gt;. Let us
know what you do with it!
&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>The Essence of JavaScript</title>
   <link href="http://blog.brownplt.org/2011/09/29/js-essence.html"/>
   <updated>2011-09-29T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2011/09/29/js-essence</id>
   <content type="html">&lt;p&gt; Back in 2008, the group decided to really understand JavaScript.  Arjun had
built a &lt;a
href=&quot;http://www.cs.brown.edu/~sk/Publications/Papers/Published/gkj-stat-anal-ajax-id/&quot;&gt;static
analysis for JavaScript&lt;/a&gt; from scratch.  Being the honest chap that he is, he
was forced to put the following caveat into the paper:&lt;/p&gt;

&lt;blockquote&gt;
&quot;We would like to formally prove that our analysis is sound.  A
sound analysis would guarantee that our tool will never raise a false alarm,
an imporant usability concern.  However, a proof of soundness would require a
formal semantics for JavaScript and the DOM in browsers, and this does not
exist.&quot;
&lt;/blockquote&gt;

&lt;p&gt;A &quot;formal semantics for JavaScript [...] does not exist&quot;?  Didn&apos;t he know
about the  official documents on such matters, the ECMAScript standard?
ECMAScript 3rd edition, the standard at the time, was around 180 pages long,
written in prose and pseudocode.  Reading it didn&apos;t help much.  It includes
gems such as this description of the &lt;code&gt;switch&lt;/code&gt; statement: &lt;/p&gt;

&lt;blockquote&gt;
&lt;pre style=&quot;font-size: 8pt&quot;&gt;
1.  Let A be the list of CaseClause items in the first
    CaseClauses, in source text order.
2.  For the next CaseClause in A, evaluate CaseClause. If there is
    no such CaseClause, go to step 7.
3.  If input is not equal to Result(2), as defined by the !== 
    operator, go to step 2.
4.  Evaluate the StatementList of this CaseClause.
5.  If Result(4) is an abrupt completion then return Result(4).
6.  Go to step 13.
7.  Let B be the list of CaseClause items in the second
    CaseClauses, in source text order.
8.  For the next CaseClause in B, evaluate CaseClause. If there is
    no such CaseClause, go to step 15.
9.  If input is not equal to Result(8), as defined by the !== 
    operator, go to step 8.
10. Evaluate the StatementList of this CaseClause.
11. If Result(10) is an abrupt completion then return Result(10).
12. Go to step 18.
...
&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt; And this is just one of 180 pages of lesser or greater eloquence.  With
&lt;em&gt;this&lt;/em&gt; as his formal reference, it&apos;s no wonder Arjun had a hard time
making soundness claims.&lt;/p&gt;

&lt;p&gt; Around the same time, Ankur Taly, Sergio Maffeis, and John Mitchell noticed
the same problem. They presented a formal semantics for JavaScript in their &lt;a
href=&quot;http://www-cs-students.stanford.edu/~ataly/Papers/aplas08.pdf&quot;&gt;APLAS 2008
paper&lt;/a&gt;.  You can find their semantics &lt;a href=&quot;http://jssec.net/&quot;&gt;here&lt;/a&gt;,
and it is a truly staggering effort, running for 40+ pages (that&apos;s at least four times easier to understand!).  However, we
weren&apos;t quite satisfied. Their semantics formalizes the ECMAScript
specification as written, and therefore inherits some of its weirdness, such as
heap-allocated &quot;scope objects&quot;, implicit coercions, etc.  We still couldn&apos;t
build tools over it, and were unwilling to do 40-page case analyses for proofs.
&lt;a href=&quot;http://www.eecs.berkeley.edu/~lmeyerov/&quot;&gt;Leo Meyerovich&lt;/a&gt;, peon
extraordinaire and friend of the blog, felt &lt;a
href=&quot;http://research.microsoft.com/apps/pubs/?id=115390&quot;&gt;the same&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&quot;Challenging current attempts to analyze JavaScript, there is no
formal semantics realistic enough to include many of the attack vectors we have
discussed yet structured and tractable enough that anyone who is not the
inventor has been able to use; formal proofs are therefore beyond the scope of
this work.&quot;&lt;/blockquote&gt;

&lt;h3&gt;How To Tackle JavaScript: The PLT Way&lt;/h3&gt;

&lt;p&gt;We decided to start smaller.  In the fall of 2009, Arjun wrote down
a semantics for the &quot;core&quot; of JavaScript that fits on just three pages (that&apos;s
60 times easier to understand!).  This is great programming languages
research&amp;mdash;we defined away the hairy parts of the problem and focused
on a small core that was amenable to proof.
  For these proofs, we could assume the
existence of a trivial desugaring that maps real JavaScript programs
into programs in the core semantics, which Arjun dubbed λ&lt;sub&gt;JS&lt;/sub&gt;.&lt;/p&gt;

&lt;p&gt; Things were looking great until one night Arjun had a few too many glasses
of wine and decided to &lt;em&gt;implement&lt;/em&gt; desugaring.  Along with 
Claudiu Saftoiu, he wrote &lt;a
href=&quot;https://github.com/brownplt/LambdaJS/blob/LambdaJS-1.0/LambdaJS/src/BrownPLT/JavaScript/Semantics/Desugar.hs&quot;&gt;a
thousand lines of Haskell&lt;/a&gt; that turns JavaScript programs into
λ&lt;sub&gt;JS&lt;/sub&gt; programs.  Even worse, they implemented an &lt;a
href=&quot;https://github.com/brownplt/LambdaJS/blob/LambdaJS-1.0/Redex/interp.ss&quot;&gt;interpreter&lt;/a&gt;
for λ&lt;sub&gt;JS&lt;/sub&gt;, so the resulting programs actually &lt;em&gt;run&lt;/em&gt;. They had therefore produced a JavaScript runtime.&lt;/p&gt;

&lt;p&gt;Believe it or not, there are other groups in the business of creating
JavaScript runtimes, namely Google, Mozilla, Microsoft, and a few more.  And
since they care about the correctness of their implementations, they have
actual test suites.  Which Arjun&apos;s system could run, and give answers for, that
may or may not be the right ones:&lt;/p&gt;

&lt;figure&gt;
&lt;img width=&quot;100%&quot; src=&quot;https://blog.brownplt.org/img/desugar.png&quot;/&gt;
&lt;/figure&gt;

&lt;p&gt; As it turns out, Arjun and Claudiu did a pretty good job.   λ&lt;sub&gt;JS&lt;/sub&gt;
agrees with Mozilla SpiderMonkey on a few thousand lines of tests.  We say
&quot;agreed&quot; and not &quot;passed&quot; because SpiderMonkey fails some of its own tests.
Without any other standard of correctness, λ&lt;sub&gt;JS&lt;/sub&gt; strives for
bug-compatibility with SpiderMonkey on those tests.&lt;/p&gt;

&lt;h3&gt;Building on  λ&lt;sub&gt;JS&lt;/sub&gt;&lt;/h3&gt;

&lt;p&gt; λ&lt;sub&gt;JS&lt;/sub&gt; is discussed in our &lt;a
href=&quot;http://www.cs.brown.edu/~sk/Publications/Papers/Published/gsk-essence-javascript/&quot;&gt;ECOOP
paper&lt;/a&gt;, but it&apos;s the work built on λ&lt;sub&gt;JS&lt;/sub&gt; that&apos;s most
interesting. We&apos;ve built the following systems ourselves:
&lt;ul&gt;

&lt;li&gt;A type-checker for JavaScript that employs a novel mix of
type-checking and flow analysis (&quot;flow typing&quot;), discussed in our &lt;a
href=&quot;http://www.cs.brown.edu/~sk/Publications/Papers/Published/gsk-flow-typing-theory/&quot;&gt;ESOP
2011 paper&lt;/a&gt;, and&lt;/li&gt;

&lt;li&gt;An extension to the above type-checker to &lt;a
href=&quot;https://blog.brownplt.org/2011/09/13/adsafety.html&quot;&gt;verify ADsafe&lt;/a&gt;, as discussed in our &lt;a
href=&quot;http://www.cs.brown.edu/~sk/Publications/Papers/Published/pegk-type-verif-js-sandbox/&quot;&gt;USENIX Security 2011&lt;/a&gt; paper.&lt;/li&gt;

&lt;/ul&gt;
Others have built on λ&lt;sub&gt;JS&lt;/sub&gt; too:
&lt;ul&gt;

&lt;li&gt;David van Horn and Matt Might use λ&lt;sub&gt;JS&lt;/sub&gt; to build an &lt;a
href=&quot;http://www.ccs.neu.edu/home/dvanhorn/pubs/vanhorn-might-preprint11.pdf&quot;&gt;analytic
framework for JavaScript&lt;/a&gt;,&lt;/li&gt;

&lt;li&gt;Rodolfo Toledo and Éric Tanter use λ&lt;sub&gt;JS&lt;/sub&gt; to specify &lt;a
href=&quot;http://swp.dcc.uchile.cl/TR/2011/TR_DCC-20110516-007.pdf&quot;&gt;aspects for
JavaScript&lt;/a&gt;,&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;http://research.microsoft.com/apps/pubs/?id=146018&quot;&gt;IBEX&lt;/a&gt;, from
Microsoft Research, uses λ&lt;sub&gt;JS&lt;/sub&gt; for its JavaScript backend to produce
verified Web browser extensions, and&lt;/li&gt;

&lt;li&gt;Others have a secret reimplementation of λ&lt;sub&gt;JS&lt;/sub&gt; in Java.
We are now enterprise-ready.&lt;/li&gt;

&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;Want to use λ&lt;sub&gt;JS&lt;/sub&gt; to write JavaScript tools?  &lt;a
href=&quot;https://github.com/brownplt/LambdaJS&quot;&gt;Check&lt;/a&gt; &lt;a
href=&quot;https://github.com/brownplt/LambdaS5&quot;&gt;out&lt;/a&gt; &lt;a
href=&quot;https://github.com/brownplt/ML-LambdaJS&quot;&gt;our&lt;/a&gt; &lt;a
href=&quot;https://github.com/brownplt/strobe&quot;&gt;software&lt;/a&gt; and let us know what you
think!&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Coming up next: &lt;/b&gt;The latest version of JavaScript, ECMAScript 5th ed.,
is vastly improved. We&apos;ve nearly finished updating our JavaScript semantics to
match ECMAScript 5th ed. Our new semantics uses the official ECMAScript test
suite and tackles problems, such as &lt;code&gt;eval&lt;/code&gt;, that the original
λ&lt;sub&gt;JS&lt;/sub&gt; elided. We&apos;ll talk about it next time. &lt;b&gt;Update:&lt;/b&gt;
We&apos;ve written about our update, &lt;a
href=&apos;https://blog.brownplt.org/2011/11/11/s5-javascript-semantics.html&apos;&gt;dubbed S5&lt;/a&gt;, its &lt;a
href=&quot;https://blog.brownplt.org/2011/12/11/getters-and-setters.html&quot;&gt;semantics for accessors&lt;/a&gt;,
and a &lt;a href=&apos;https://blog.brownplt.org/2012/01/31/s5-wat.html&apos;&gt;particularly interesting
example&lt;/a&gt;.

&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>ADsafety</title>
   <link href="http://blog.brownplt.org/2011/09/13/adsafety.html"/>
   <updated>2011-09-13T00:00:00+00:00</updated>
   <id>http://blog.brownplt.org/2011/09/13/adsafety</id>
   <content type="html">&lt;figure style=&quot;float: right;&quot;&gt;&lt;img src=&quot;https://blog.brownplt.org/img/adsafety.png&quot; /&gt;&lt;/figure&gt;

&lt;p&gt; A &lt;i&gt;mashup&lt;/i&gt; is a webpage that mixes and mashes content from various
sources. Facebook apps, Google gadgets, and various websites with embedded maps
are obvious examples of mashups. However, there is an even more pervasive use
case of mashups on the Web. Any webpage that displays third-party ads is a
mashup. It&apos;s well known that third-party content can include third-party
cookies; your browser can even block these if you&apos;re concerned about &quot;tracking
cookies&quot;. However, third party content can also include third-party JavaScript
that can do all sorts of wonderful and malicious things (&lt;a
href=&quot;http://www.bbc.co.uk/news/technology-12891182&quot;&gt;just&lt;/a&gt; &lt;a
href=&quot;http://news.cnet.com/8301-27080_3-20000898-245.html&quot;&gt;some&lt;/a&gt; &lt;a
href=&quot;http://www.networkworld.com/news/2011/030111-malware-ads-hit-london-stock.html&quot;&gt;examples&lt;/a&gt;).
&lt;/p&gt;

&lt;p&gt;Is it possible to safely embed untrusted JavaScript on a page? Google Caja,
Microsoft Web Sandbox, and ADsafe are &lt;i&gt;language-based Web sandboxes&lt;/i&gt; that
try to do so. Language-based sandboxing is a programming language technique
that restricts untrusted code using static and runtime checks and rewriting
potential dangerous calls to safe, trusted functions.&lt;/p&gt;

&lt;p&gt;Sandboxing JavaScript, with all its corner cases, is particularly hard. A
single bug can easily break the entire sandboxing system. JavaScript sandboxes
do not clearly state their intended guarantees, nor do they clearly argue why
they are safe.  &lt;figure style=&quot;float: left;&quot;&gt; &lt;img
src=&quot;https://blog.brownplt.org/img/adsafe-settimeout.png&quot; /&gt; &lt;figcaption&gt;This is how ADsafe
works.&lt;/figcaption&gt; &lt;/figure&gt; &lt;/p&gt;

&lt;h3&gt;Verifying Web Sandboxes&lt;/h3&gt;

&lt;p&gt; A year ago, we embarked on a project to verify &lt;a
href=&quot;http://www.adsafe.org/&quot;&gt;ADsafe&lt;/a&gt;, &lt;a
href=&quot;http://www.crockford.com/&quot;&gt;Douglas Crockford&lt;/a&gt;&apos;s Web sandbox. ADsafe is
admittedly the simplest of the aforementioned sandboxes. But, we were also
after the shrimp bounty that Doug offers for sandbox-breaking bugs:

&lt;blockquote cite=&quot;http://tech.groups.yahoo.com/group/caplet/message/44&quot;&gt;
Write a program [...] that calls the alert function when run on any browser. If the program produces no errors when linted with the ADsafe option, then I will buy you a plate of shrimp. (&lt;a href=&quot;http://tech.groups.yahoo.com/group/caplet/message/44&quot;&gt;link&lt;/a&gt;)
&lt;/blockquote&gt;

A year later, we&apos;ve produced a &lt;a
href=&quot;http://www.cs.brown.edu/~sk/Publications/Papers/Published/pegk-type-verif-js-sandbox/&quot;&gt;USENIX
Security paper&lt;/a&gt; on our work, which we &lt;a
href=&quot;http://www.usenix.org/events/sec11/stream/politz/index.html&quot;&gt;presented&lt;/a&gt;
in San Francisco in August. The paper discusses the many common techniques
employed by Web sandboxes and discusses the intricacies of their
implementations. (TLDR: JavaScript and the DOM are really hard.) Focusing on
ADsafe, it precisely states what ADsafety actually means. The meat of the paper
is our approach to verifying ADsafe using types. Our verification leverages our
earlier work on &lt;a
href=&quot;http://www.cs.brown.edu/~sk/Publications/Papers/Published/gsk-essence-javascript/&quot;&gt;semantics&lt;/a&gt;
and &lt;a
href=&quot;http://www.cs.brown.edu/~sk/Publications/Papers/Published/gsk-flow-typing-theory/&quot;&gt;types&lt;/a&gt;
for JavaScript, and also introduces some new techniques:&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Check out the &lt;span style=&quot;font-size: large;&quot;&gt;★&lt;/span&gt;s and &lt;span
style=&quot;font-size: large;&quot;&gt;☠&lt;/span&gt;s in our object types; we use them to
type-check &quot;scripty&quot; features of JavaScript. &lt;span style=&quot;font-size:
large;&quot;&gt;☠&lt;/span&gt; marks a field as &quot;banned&quot; and &lt;span style=&quot;font-size:
large;&quot;&gt;★&lt;/span&gt; specifies the type of all other fields.&lt;/li&gt;

&lt;li&gt;We also characterize JSLint as a type-checker. The Widget type presented in
the paper specifies, in 20 lines, the syntactic restrictions of JSLint&apos;s
ADsafety checks.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Unlike conventional type systems, ours does not prevent runtime errors.
After all, stuck programs are safe because they trivially don&apos;t execute any
code. If you think type systems only catch &quot;method not found&quot; errors, you
should have a look at ours.&lt;/p&gt;

&lt;p&gt;We found bugs in both ADsafe and JSLint that manifested as type errors. We reported all of them and they were promptly fixed by Doug Crockford. A big thank you to Doug for his encouragement, for answering our many questions, and for buying us every type of shrimp dish in the house.
&lt;div class=&quot;center&quot;&gt;
&lt;figure&gt; &lt;img class=&quot;center&quot; src=&quot;https://blog.brownplt.org/img/shrimp-bounty.jpg&quot; width=&quot;320&quot; /&gt; &lt;figcaption&gt;Doug Crockford, Joe, Arjun, and seven shrimp dishes&lt;/figcaption&gt; &lt;/figure&gt; &lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;
Learn more about ADsafety!  Check out:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
  The &lt;a href=&quot;http://www.cs.brown.edu/research/plt/dl/adsafety/v1&quot;&gt;paper,
  code, and proofs&lt;/a&gt;;
&lt;/li&gt;
&lt;li&gt;
  &lt;a href=&quot;http://www.usenix.org/multimedia/sec11politz&quot;&gt;Video&lt;/a&gt; of Arjun presenting at USENIX Security;
&lt;/li&gt;
&lt;li&gt;
  &lt;a href=&quot;http://www.adsafe.org&quot;&gt;ADsafe&lt;/a&gt; and &lt;a href=&quot;http://www.jslint.org&quot;&gt;JSLint&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 
</feed>
