187 research outputs found
A Core Calculus for Documents
Passive documents and active programs now widely comingle. Document languages
include Turing-complete programming elements, and programming languages include
sophisticated document notations. However, there are no formal foundations that
model these languages. This matters because the interaction between document
and program can be subtle and error-prone. In this paper we describe several
such problems, then taxonomize and formalize document languages as levels of a
document calculus. We employ the calculus as a foundation for implementing
complex features such as reactivity, as well as for proving theorems about the
boundary of content and computation. We intend for the document calculus to
provide a theoretical basis for new document languages, and to assist designers
in cleaning up the unsavory corners of existing languages.Comment: Published at POPL 202
ADsafety: Type-Based Verification of JavaScript Sandboxing
Web sites routinely incorporate JavaScript programs from several sources into
a single page. These sources must be protected from one another, which requires
robust sandboxing. The many entry-points of sandboxes and the subtleties of
JavaScript demand robust verification of the actual sandbox source. We use a
novel type system for JavaScript to encode and verify sandboxing properties.
The resulting verifier is lightweight and efficient, and operates on actual
source. We demonstrate the effectiveness of our technique by applying it to
ADsafe, which revealed several bugs and other weaknesses.Comment: in Proceedings of the USENIX Security Symposium (2011
Teaching Programming Languages by Experimental and Adversarial Thinking
We present a new approach to teaching programming language courses. Its essence is to view programming language learning as a natural science activity, where students probe languages experimentally to understand both the normal and extreme behaviors of their features. This has natural parallels to the "security mindset" of computer security, with languages taking the place of servers and other systems. The approach is modular (with minimal dependencies), incremental (it can be introduced slowly into existing classes), interoperable (it does not need to push out other, existing methods), and complementary (since it introduces a new mode of thinking)
A Grounded Conceptual Model for Ownership Types in Rust
Programmers learning Rust struggle to understand ownership types, Rust's core
mechanism for ensuring memory safety without garbage collection. This paper
describes our attempt to systematically design a pedagogy for ownership types.
First, we studied Rust developers' misconceptions of ownership to create the
Ownership Inventory, a new instrument for measuring a person's knowledge of
ownership. We found that Rust learners could not connect Rust's static and
dynamic semantics, such as determining why an ill-typed program would (or would
not) exhibit undefined behavior. Second, we created a conceptual model of
Rust's semantics that explains borrow checking in terms of flow-sensitive
permissions on paths into memory. Third, we implemented a Rust compiler plugin
that visualizes programs under the model. Fourth, we integrated the permissions
model and visualizations into a broader pedagogy of ownership by writing a new
ownership chapter for The Rust Programming Language, a popular Rust textbook.
Fifth, we evaluated an initial deployment of our pedagogy against the original
version, using reader responses to the Ownership Inventory as a point of
comparison. Thus far, the new pedagogy has improved learner scores on the
Ownership Inventory by an average of 9% ().Comment: Published at OOPSLA 202
The Next 700 Semantics: A Research Challenge
Modern systems consist of large numbers of languages, frameworks, libraries, APIs, and more. Each has characteristic behavior and data. Capturing these in semantics is valuable not only for understanding them but also essential for formal treatment (such as proofs). Unfortunately, most of these systems are defined primarily through implementations, which means the semantics needs to be learned. We describe the problem of learning a semantics, provide a structuring process that is of potential value, and also outline our failed attempts at achieving this so far
Event Loops as First-Class Values: A Case Study in Pedagogic Language Design
The World model is an existing functional input-output mechanism for
event-driven programming. It is used in numerous popular textbooks and
curricular settings. The World model conflates two different tasks -- the
definition of an event processor and its execution -- into one. This conflation
imposes a significant (even unacceptable) burden on student users in several
educational settings where we have tried to use it, e.g., for teaching physics.
While it was tempting to pile on features to address these issues, we instead
used the Scheme language design dictum of removing weaknesses that made them
seem necessary. By separating the two tasks above, we arrived at a slightly
different primitive, the reactor, as our basis. This only defines the event
processor, and a variety of execution operators dictate how it runs. The new
design enables programmatic control over event-driven programs. This simplifies
reflecting on program behavior, and eliminates many unnecessary curricular
dependencies imposed by the old design. This work has been implemented in the
Pyret programming language. The separation of concerns has enabled new
curricula, such as the Bootstrap:Physics curriculum, to take flight. Thousands
of students use this new mechanism every year. We believe that reducing
impedance mismatches improves their educational experience
Dependently Typing R Vectors, Arrays, and Matrices
The R programming language is widely used in large-scale data analyses. It
contains especially rich built-in support for dealing with vectors, arrays, and
matrices. These operations feature prominently in the applications that form
R's raison d'\^etre, making their behavior worth understanding. Furthermore,
ostensibly for programmer convenience, their behavior in R is a notable
extension over the corresponding operations in mathematics, thereby offering
some challenges for specification and static verification.
We report on progress towards statically typing this aspect of the R
language. The interesting aspects of typing, in this case, warn programmers
about violating bounds, so the types must necessarily be dependent. We explain
the ways in which R extends standard mathematical behavior. We then show how
R's behavior can be specified in LiquidHaskell, a dependently-typed extension
to Haskell. In the general case, actually verifying library and client code is
currently beyond LiquidHaskell's reach; therefore, this work provides
challenges and opportunities both for typing R and for progress in
dependently-typed programming languages.Comment: 10 page
Conceptual Mutation Testing for Student Programming Misconceptions
Context: Students often misunderstand programming problem descriptions. This
can lead them to solve the wrong problem, which creates frustration, obstructs
learning, and imperils grades. Researchers have found that students can be made
to better understand the problem by writing examples before they start
programming. These examples are checked against correct and wrong
implementations -- analogous to mutation testing -- provided by course staff.
Doing so results in better student understanding of the problem as well as
better test suites to accompany the program, both of which are desirable
educational outcomes.
Inquiry: Producing mutant implementations requires care. If there are too
many, or they are too obscure, students will end up spending a lot of time on
an unproductive task and also become frustrated. Instead, we want a small
number of mutants that each correspond to common problem misconceptions. This
paper presents a workflow with partial automation to produce mutants of this
form which, notably, are not those produced by mutation-testing tools.
Approach: We comb through student tests that fail a correct implementation.
The student misconceptions are embedded in these failures. We then use methods
to semantically cluster these failures. These clusters are then translated into
conceptual mutants. These can then be run against student data to determine
whether we they are better than prior methods. Some of these processes also
enjoy automation.
Knowledge: We find that student misconceptions illustrated by failing tests
can be operationalized by the above process. The resulting mutants do much
better at identifying student misconceptions.
Grounding: Our findings are grounded in a manual analysis of student examples
and a quantitative evaluation of both our clustering techniques and our process
for making conceptual mutants. The clustering evaluation compares against a
ground truth using standard cluster-correspondence measures, while the mutant
evaluation examines how conceptual mutants perform against student data.
Importance: Our work contributes a workflow, with some automation, to reduce
the cost and increase the effectiveness of generating conceptually interesting
mutants. Such mutants can both improve learning outcomes and reduce student
frustration, leading to better educational outcomes. In the process, we also
identify a variation of mutation testing not commonly discussed in the software
literature
From Macros to DSLs: The Evolution of Racket
The Racket language promotes a language-oriented style of programming. Developers create many domain-specific languages, write programs in them, and compose these programs via Racket code. This style of programming can work only if creating and composing little languages is simple and effective. While Racket\u27s Lisp heritage might suggest that macros suffice, its design team discovered significant shortcomings and had to improve them in many ways. This paper presents the evolution of Racket\u27s macro system, including a false start, and assesses its current state
- …