dark mode light mode Search Menu
Search

Racket Christmas Tree

Freestocks.org on Flickr

The winter holidays are upon us, whether you’re celebrating Christmas, Hanukkah, Kwanzaa, or simply enjoying time with your loved ones. In today’s coding activity, we’ll use Racket to decorate a virtual pine tree with multicoloured bulbs, ornaments, and gewgaws galore!

SETUP

Racket is a functional programming language. This means that the code is structured a little bit differently than traditional imperative languages like Python or JavaScript. What matters most, though, is that Racket has tons of simple built-in image functions that are perfect for creating our festive masterpiece. To start, navigate to https://www.wescheme.org/.

Click on the “Start Coding” Button to access the editor:

SOME BASIC SHAPES

In Racket, every function call is done inside brackets, staring with the function name followed by a list of parameters. Let’s try out some basic shapes:

(triangle 500 "solid" "green")
(star 50 "solid" "yellow")
(circle 25 "solid" "red")

See the pattern? The first word is the name of Racket’s built-in function, followed by the size you want, the type of fill, and the colour. Feel free to play around with these parameters and see what happens. What about making a blue circle, or shapes that have an “outline” instead of a “solid” fill parameter? Hit the “run” button at the top-left of the screen to see your results in the console.

To create our tree, we’re going to layer these shapes on top of each other, using two new functions: empty-scene and place-image.

We use the “empty-scene” function to specify the size of our blank background. The two arguments are the “height” and “width” pixel values:

(empty-scene 700 700)

“Place-image” takes four arguments: (1) the image that’s going on top, (2) the x and (3) y coordinates for the centre of this image, and (4) the background. In this case, the image we want to use is the result of our triangle function, and the background is the result of the empty-scene function. Since our background is 700 x 700, and we want our tree to be smack in the centre, we’ll use the coordinates (350, 350).

To write this code, copy the entire triangle function and empty-scene function, brackets and all, and nest them inside the place-image function. Make sure you’re nesting them in the proper order! And watch out for those brackets — double check that every opening bracket has a closing bracket in the right spot.

(place-image (triangle 500 "solid" "green")
             350
             350
             (empty-scene 700 700))

DEFINING VARIABLES

That last function’s a bit confusing to read, right? We’re placing function calls inside each other like Russian dolls! This “nesting” structure can make functional programming can seem a bit strange at first, so to make life easier, we can simplify our syntax by “defining” some variables.

(define tree (triangle 500 "solid" "aquamarine"))

The “define” function binds a “literal” value (numbers, text, objects) to a symbol / variable of our choice. So, we can define our triangle as “tree”, and our empty space as “bg”, and use those keywords in the “place-image” function instead. A bit easier on the eyes and the brain! Let’s also create variables for our other shapes:

(define tree (triangle 500 "solid" "aquamarine"))
(define top (star 50 "solid" "gold"))
(define bulb_red (circle 25 "solid" "red"))
(define bg (empty-scene 700 700))

(place-image tree 350 350 bg)

LAYER BY LAYER

“Place-image” can only layer images one at a time, which means we’re stuck making a new place-image function call for every new ornament. From a programming perspective, this means that the result of the first “place-image” function (where the tree is placed on a background) becomes the “image” parameter of the second “place-image” function:

(place-image top 350 110 (place-image tree 350 350 bg))

You’re welcome to keep nesting function calls just like that — or you can break them up by defining variables in steps. For example:

(define step1 (place-image tree 350 350 bg))
(define step2 (place-image top 350 110 step1))
step2

Since the “define” only binds without displaying, to make our tree to appear we need to print out the end result at the end of our code.

CREATING NEW ORNAMENTS

Using this method, you can add as many new ornaments as you want — just keep layering! Leave bulbs behind and discover the diverse world shapes that Racket has to offer, including the rhombus and the radial-star:

(define orn1 (rhombus 40 45 "solid" "magenta"))
(define orn2 (radial-star 8 8 25 "solid" "yellow"))

When placing a new ornament, I recommend starting at the centre of the tree (position 350 350) and then tweaking these x and y variables to see what the ornament looks like a little to the left, a little down, or a little to the right. Increasing “x” moves the ornament right; decreasing goes left. Similarly, increasing “y” moves the ornament down, and decreasing goes back up:

(define tree (triangle 500 "solid" "aquamarine"))
(define top (star 50 "solid" "gold"))
(define bulb_red (circle 25 "solid" "red"))
(define bulb_blue (circle 25 "solid" "blue"))
(define bg (empty-scene 700 700))
(define orn1 (rhombus 40 45 "solid" "magenta"))
(define orn2 (radial-star 8 8 25 "solid" "yellow"))

(define step1 (place-image tree 350 350 bg))
(define step2 (place-image top 350 110 step1))
(define step3 (place-image bulb_blue 425 400 step2))
(define step4 (place-image bulb_red 275 500 step3))
(define step5 (place-image bulb_red 325 275 step4))
(define step6 (place-image orn1 250 375 step5))
(define step7 (place-image orn1 480 500 step6))
(define step8 (place-image orn2 350 350 step7))

step8

Don’t forget to call the latest result at the end of your code. If you forget to update the step number, you’ll be stuck displaying an old version of the tree.

Have fun, and Happy Holidays!

Learn More

Racket Documentation

https://docs.racket-lang.org/teachpack/2htdpimage.html

Create Shapes and Colours with Racket

https://kidscodecs.com/shapes-colors-racket/

A Beginner-Friendly Intro into Functional Programming

https://codeburst.io/a-beginner-friendly-intro-to-functional-programming-4f69aa109569

Functional Programming Paradigm

https://www.geeksforgeeks.org/functional-programming-paradigm/

Lambda Calculus

https://kidscodecs.com/lambda-calculus/

Declarative vs Imperative Programming

https://codeburst.io/declarative-vs-imperative-programming-a8a7c93d9ad2