The Power of Functional Languages
Bootstrap:Algebra is different than some other integrated curriculums in that it uses a functional programming language called Racket. Racket is a solid programming platform, but may not be as familiar or well-known as other industry-standard languages like Python, Java, or C. This raises the question, why does Bootstrap:Algebra begin with Racket?
Not all Languages are Mathematical
Racket is what is called a functional programming language. It treats functions, variables and numbers in a way very similar to math, which makes comprehending program behavior easier for students with little to no programming background. Functional languages reinforce - rather than undermine - the math that students already need to learn in school.
Look at this programming sample. Say we needed a variable x to start at 0 and increase by 1 every time something happened, like the user pressing the spacebar.
x = 0 // Create a variable called x and set it to 0
x = x + 1 // Increase x by 1
From a math perspective, there are seemingly two declarations of x at odds with each other, and "x = x + 1" looks like an equation with no solution. If a student saw this, they might be tempted to try and solve it by "plugging in" the value of x = 0 into the second equation, resulting in 0 = 1. The student's assumption that x = x + 1 is a thing to be solved, rather than a process, leads to confusion, especially for those who are still just getting comfortable with the nature of variables.
Functional languages do not default to these methods of programming, and make it natural to program without them. Functional languages behave more like the mathematics that students and teachers are already familiar with while also providing opportunities for discovery and discussions of the benefits and limitations of different programming languages.
From Writing Examples to Introductory Testing
In a classroom setting, it's common to start solving a problem by first working through some examples. A math or physics teacher might start out talking about the motion of a train, asking students to think about how fast the train is moving after 1 second, 2 seconds, and so on. Once they've worked through concrete examples, the students are asked to "find the rule", or a way to represent their thinking, and arrive at the generalized solution. For computing-infused courses, this is where the programming starts - after a lot of valuable thinking has already happened! The functional languages we use in Bootstrap's courses gives us two significant wins over traditional imperative languages.
First, our languages include syntax that allows students to program the examples the themselves. This creates a mutually-reinforcing value proposition for students: programming helps you write examples, and writing examples helps you program. And by leveraging the classroom practices are already commonplace, it raises the value of programming for teachers everywhere. For the math student, developing the ability to create a function model and defend that model with multiple examples is a high-level skill that will benefit the student as they moves forward in math studies. Activities such as these also support the Standards for Mathematical Practice on multiple levels as well as supporting a modeling-based classroom environment. For the math teacher, teaching programming concurrently with math using a functional language like Racket enables them to continue using their preferred current pedagogical practices. This is especially beneficial to teachers who do not have a lot of programming experience, as the methods they are comfortable with are built right in.
Secondly, this allows us to take a concept that is often reserved for advanced programming classes - software testing - and dramatically lower the barriers for introducing it to novices. Testing is extremely complex in imperative languages, since functions are not guaranteed to be "pure". For example, a function that increments a counter and returns the result will produce an output based on when it is called, as opposed to what the input is. Encoding notions of state and time are extremely difficult, which is why testing is considered an advanced topic. But in a functional setting, functions rely purely on their inputs, and students can write simple, test-like constructs merely by writing examples of what their functions should produce and then automatically running them against their solutions. Combined with functional languages, that practice can now be leveraged to introduce a lightweight notion of testing - without any extra effort on the part of the student or teacher!
What might this look like in the classroom? In Bootstrap:Algebra, students are faced with the question of how to create a function that will move an image to the right. By moving through the process from concrete examples to representational thinking to a general, more abstract solution, students use their own experience and knowledge base as a solid foundation for their programming.
Concrete Examples - Students define the problem at hand and think about a way to break it down into smaller parts. Using a coordinate plane, students might define the coordinates of an object and its coordinates after one horizontal shift. Students could write several examples before and after a horizontal shift that will later be used in their program.
Representational Thinking - Keeping the problem definition in mind, the students use the examples to write or explain the pattern behind how the coordinates are changing.
Abstract Solution - Students look for a way to model the way the variable is changing and how. Students write their ideas for a function model and discuss. Once students concur on a solution, they can translate it, along with their examples, to the programming syntax and run the program to check the accuracy of their solution.
An Intentional Language Path
Not all of the Bootstrap curricula use Racket. As students advance in their programming abilities, they may start to notice limitations or wish they could create more powerful programs using what they've learned.
In addition to mathematical behavior, Racket provides a syntax that is ideal for expressing mathematical concepts. However, many students will wind up learning an imperative language like Python. Instead of jumping right into a language and a foreign syntax and foreign behavior, the team has developed a new programming language called Pyret that combines the mathematical behavior of Racket with syntax that is similar to Python's. This creates a smooth transition for students who move forward in computer programming, and for those who don't, it facilitates learning rigorous programming without undermining concepts learned in their math classes.
Computer programmers have to learn a variety of languages as a part of their job, because computer languages have different strengths for different needs. It shows the students how processes can be done in different ways and with new syntax. It also encourages students to ask questions and explore what is possible in different languages. What language makes websites work? What language is that favorite video game written in?
In learning Pyret, students have access to all the skills they learned in Racket. All of the same familiar functions, like circle and star, are still there, just with slightly different syntax. The Design Recipe also reflects the small changes in syntax, but is still functionally the same.
Bootstrap:Algebra uses Racket to provide more scaffolding and opportunities for math teachers to connect to classroom material and current pedagogical methods. The curriculum's integration of math and computer science is a proven method that enhances student learning. It provides new ways to help students with common stumbling blocks, especially in understanding functions, and finally, Bootstrap has constructed a path that takes students from Racket to Pyret and beyond. Using a functional language that supports modern pedagogy makes integrating computer science with math intuitive and fun for students and teachers alike.
Posted March 15, 2019