Functional programming for kids?
A long, long time ago, in the pre-pandemic era, just after ScalaDays in Lausanne, we made a short trip to the Alps. Together with Jacek Kunicki and Michał Mital, we briefly talked on whether it would be possible to teach functional programming to kids.
Learning-oriented programming environments are usually imperative. For example, in the most popular one – Scratch – you place blocks representing actions that should be run in a sequence. Later, kids or young adults are introduced to "normal" programming languages such as Python or JavaScript, which are imperative as well.
Given that functional programming requires adopting a different mindset, and often offers a unique perspective on the problem to be solved, can we somehow introduce elements of FP at an earlier stage?
Circles: edit live
Back to Logo
One of my first programming languages was Logo, also known as "turtle graphics". I still have a lot of sentiment for it, and despite its age, I think it might be a great teaching tool. Logo programming involves writing text. This is close to what almost all coding looks like nowadays, as opposed to systems like Scratch that don't resemble "real" programming in that aspect. On the other hand, there's the visual component, which provides a quick feedback loop and makes it easy to visualise your progress.
However, programming environments supporting the Logo language feel rather old-fashioned. That's why I decided, as a side-project, to create a Logo-like language, but modernised, accessible through a browser, with a program-sharing mechanism. That's how Shelly was born. The feedback loop in Shelly is even shorter since the program is evaluated as you type.
The syntax of Shelly doesn't resemble Logo at all, it rather draws inspiration from contemporary programming languages. However, the idea is the same: there's a turtle that is controlled by instructions. The turtle draws lines and shapes as it moves, using various colours and styles. The basic commands, going forward (fw
), or turning right (right
) remain the same as in the original.
There is a twist, however, as the Shelly language contains some elements of functional programming. First of all, everything in Shelly is an expression, and hence has a value. Secondly, functions are first-class values. And finally, everything is immutable (however, there are hardly any data structures in Shelly; but there are no mutable variables).
Turtle instructions as a value
I think especially the first characteristic – that everything is an expression and has a value – is significant. But what's the value of the expression telling the turtle to go forward 100 steps, that is fw 100
?
Behind the scenes, the value of each expression is a pair: the computed value and a list of instructions for the turtle. In the case of fw 100
, the computed value is ()
("no-value" or "unit" or "void", depending on how your favourite language calls it), and the list of instructions is [ fw 100 ]
. In the case of 2+2
, the computed value is 4
and the list of instructions is []
(empty array).
If you're familiar with monads, you can think of every computation in Shelly as if it was run within a writer monad.
Given a list of expressions, the turtle instructions are concatenated, so fw 100; right 90
works as expected. In the end, the whole program you write yields a value plus the turtle instructions to run.
Star: edit live
Turtle expressions in practice
Does this have any practical implications, though? Might it influence the way you write turtle-controlling code?
I think so! For example, take the following snippet:
let forwardRight = (
fw 100
right 90
)
forwardRight
forwardRight
fw right: edit live
We are using the result of the forwardRight
expression twice, which means that the value of that whole expression will contain four instructions for the turtle (forward, right, forward, right). So extracting common code sequences becomes trivial, and works exactly as you would expect.
Yes, that's what some call referential transparency in the world of turtle graphics.
This might seem insignificant, but I found that it's the basic, simple characteristics of functional programming (namely: everything is an expression, controlled side effects, immutability) that make all the difference.
Triangle fractal: edit live
Does FP at this stage make sense?
Turtle-expressions might sound nice, but does it matter that everything has a value in the rather simple programs that kids write in a tool such as Shelly?
Probably not that much. In the short programs that are needed to solve the Shelly challenges, the solutions would be almost the same when using an imperative version of the Shelly/Logo language. But who knows – maybe for someone who will write more complex programs using Shelly, its functional aspects will start forging a functional mindset?
If you'd like to get a feel of what it's like to program using "functional Logo" yourself, there's the challenge mode to get started, the free-form drawing mode, and finally the animation mode. Give Shelly a spin and let us know what you think, both about the platform and its functional aspects.