28 Pyret vs. Python
For the curious, we offer a few examples here to justify our frustration with Python for early programming.
Python | Pyret |
Python exposes machine arithmetic by default. Thus, by default,
| Pyret implements exact arithmetic, including rationals, by default. In
Pyret, |
Python | Pyret |
Understanding the difference between creating a variable and updating its value is a key learning outcome, along with understanding variables’ scopes. Python explicitly conflates declaration with update, and has a tangled history with scope. | Pyret is statically scoped, and goes to great lengths— |
Python | Pyret |
Python has a weakly-defined, optional mechanism of annotations that was added late in the language’s design, which conflates values and types. | Drawing on lessons learned from our several prior research projects on adding types to languages after-the-fact, Pyret was designed with typability from the start, with several subtle design choices to enable this. Pyret also has support (currently dynamic) for refinement-type annotations. |
Python | Pyret |
Python’s annotation mechanism has no notion of refinements. | To prepare students for modern programming languages with rich type systems, Pyret’s annotation syntax supports refinements. However, these are checked dynamically, so that students do not need to satisfy the vagaries of any particular proof assistant. |
Python | Pyret |
Python has weak built-in support for testing. While it has extensive professional libraries to test software, these impose a non-trivial burden on learners, as a result of which most introductory curricula do not use them. | First, a curriculum that proclaims reliability must put testing at its
heart. Second, our pedagogy places heavy emphasis on the use of examples, and
in particular the building-up of abstractions from concrete instances. For both
these reasons, Pyret has extensive support in the language itself— |
Python | Pyret |
Modern testing goes well beyond unit-tests. Furthermore, property-based testing is a very useful gateway to thinking about formal properties. In Python, this is only available through libraries. | Pyret has convenient language features— |
Python | Pyret |
State is ubiquitous in libraries. | State is an important but also complicated part of programming. Pyret nudges students to program without state while still permitting the full range of stateful programming. This comes with safeguards both linguistic (e.g., variables are immutable unless declared otherwise) and in output (e.g., mutable fields are displayed to alert the student that the value may change or may even have already changed). |
Python | Pyret |
Equality comparison is simplistic and in line with most other professional languages. | Equality is in fact subtle, and useful as a pedagogic device. Therefore, Pyret has a carefully-designed family of equality operators that are not only of practical value but also have pedagogic use. |
Python | Pyret |
Images are not values in the language. You can write a program to produce an image, but you can’t just view it in your programming environment. | Images are values. Pyret can print an image just like it can a string or a number (and why not?). Images are fun values, but they aren’t frivolous: they are especially useful for demystifying and explaining important but abstract issues like function composition. |
Python | Pyret |
The language doesn’t have a built-in notion of reactive programs. | Reactivity is a core concept in the language, and the subject of both design and implementation research. |
Python | Pyret |
Python’s error messages are not added with novices as a primary audience. | Novices make many errors. They can be especially intimidated by error reports, and can feel discouraged about causing errors. Thus, Pyret’s error messages are the result of nearly a decade of research. In fact, some educators have created pedagogic techniques that explicitly rely on the nature and presentation of information in Pyret’s errors. |
Python | Pyret |
Python has begun to suffer from complexity creep that we believe serves professionals at the expense of novices. For example, the result of map in Python is actually a special generator value. This can lead to outcomes requiring extra explanation, like map(str, [1, 2, 3]) producing <map object at 0x1045f4940>. Type hints (discussed above) are another example. | Since Pyret’s target audience is novice programmers programming in the style of this book, our primary goal when adding any feature is to preserve the early experience and avoid surprises. |
Python | Pyret |
Data definitions are central to computer science, but Python over-relies on built-in data structures (especially dictionaries) and makes user-defined ones unwieldy to create. | Pyret borrows from the rich tradition of languages like Standard ML, OCaml, and Haskell to provide algebraic datatypes, whose absence often forces programmers to engage in unwieldy (and inefficient) encoding tricks. |
Python | Pyret |
Python has several more rough corners that can lead to unexpected and
undesirable outcomes. For instance, | Pyret is designed from the ground-up to avoid all these problems. |