# Painting with functions
Table of Contents
Functions are everywhere in programming. If you’re confused by the concept, it makes sense to take some time to understand them now, and save yourself from a lot of pain.
In its simplest form, a function is a reusable sequence of instructions. A label for lines of code.
InstructionsLink to heading
An instruction is the programmer telling the computer to do something.
If you tell your dog to sit, or bark, or shake, that’s an instruction.
We’ll start with a computer that already knows how to draw simple shapes:
By the end of the article, you’ll be able to make relatively complex paintings using these simple shapes, by combining them using functions.
Let’s get to know what instructions we can work with.
ShapesLink to heading
We can draw rectangles, circles, and triangles. What we put in the parentheses is information about where to draw them, and what color.
In the editor above, change the numbers until you understand what they do. Don’t continue until you can make the circle fit inside the rectangle!
ComposingLink to heading
What can we do with this? A whole lot!
Let’s combine 2 instructions, and draw a tree:
Looks lonely! Let’s make it a little smaller, and add a few more trees:
See how, to move an exact copy 150 pixels to the right, we just add 150 to the x coordinates (how far to the right it is). We subtract to go left.
Apart from that x-shifting, the rest of the code is the same for all the trees.
Writing the same code with some small variations gets tedious over time: say I wanted 10 trees, that’s a lot to write or copy paste!
GeneralizingLink to heading
That’s where functions come in: they get rid of this repetitiveness.
Let’s start with that center tree:
We turned the center tree into function tree() { ... }, and executed the lines inside it with tree().
We have defined the tree function as drawing a rectangle and a triangle, in a tree layout, just like we did before.
You can see the result is indistinguishable! It’s exactly the same picture.
Let’s try to replace our other trees, to avoid the repetitiveness:
That’s a problem: the program drew 3 trees, but they’re all on top of each other.
The rectangles and triangles for each tree are drawn at exactly the same positions, there’s nothing to tell each tree that it should be to the left or to the right (-150 and +150).
The function we created is not very useful if it always draws the tree in the same place. Let’s fix that.
When we define a function, we can declare parameters (sometimes called arguments) to specify variations: changes in the code that will be run.
To know what value to use as the offset, we look at how the function is used, e.g. tree(150) means that:
- the
offsetwill be150, so 290 + offsetwill be290 + 150 = 440
And 440 pixels from the left edge is where the rectangle for the trunk of the right tree starts.
The tree function now knows where to put its rectangle and triangle, based on the offset parameter.
SimplifyingLink to heading
It’s more intuitive to say “put a tree at x=450” than “put a tree 150 pixels after 300 pixels”.
We can make both our function and our usage simpler, by allowing tree(x) to put the tree directly at x rather than 300 + x:
Now tree(100) creates a tree whose center is 100 pixels from the left.
And we can do the same for y:
You can now use tree as an instruction!.
Functions are themselves instructions, and can be used in other functions.
For example, we can make a forest function that uses our new tree function, several times.
This produces exactly the same result as our previous example.
But it’s now in a function, which means we can have more fun with less effort!
Imagine how many lines of code that would be if we didn’t use functions!
It’s 15 rectangles and 15 triangles, all with different positions. It would be a mess:
Not only would it be harder to tell what’s going on just by reading the code (are those trees, or pistacho chocolate bars?), but it would also be more time consuming to make changes.
Imagine we wanted to change the color of our tree trunk to brown: we’d have to change 15 lines, instead of just 1 in the tree function!
Hopefully you now understand why functions are in your best interest, even if it seems like an extra step.
LibraryLink to heading
To achieve something complex, you want to have a few good functions available.
Sometimes you might find that someone else already wrote some functions for you to use. In programming, we call this a library: a reusable source of knowledge we can leverage.
So let’s build a library for your drawing needs!
We already have functions for trees and forests, let’s add more.
BackdropLink to heading
Every painting needs a backdrop.
This doesn’t need to be a function, as we only need one backdrop, but “drawing the backdrop” is a reasonable instruction to make our life easier, later.
We drew the sky.
A rectangle that fills the screen: starts at the top left corner (0, 0), and is the same size as the canvas (600 wide, and 500 pixels high).
Or is it an ocean, or a lake? Adding a sun would help clarify that.
Note that the sun circle can go on top of the sky rectangle.
Instructions happen in a sequence, order matters: if you first draw a blue rectangle, and then a yellow circle on top, you can see the yellow circle.
If you do it the other way around, the rectangle covers the circle and you don’t see it. You can try it, by putting the rectangle after the circle in the editor above.
Now we just need some surface to put trees on:
We have a backdrop! Let’s see how we would use it.
Adding the trees is as easy as calling (executing) our tree function:
Let’s remove the trees for now, and work on another function in our library.
CloudLink to heading
Clouds look nice in paintings! Especially when they’re all puffy.
A simple way to approximate a puffy shape, is with a few circles:
That looks nice! A cloud centered on x=150, and y=150
Once we have the function for it, we can add as many clouds as we like, with little effort:
MountainLink to heading
The most visually pleasing paintings, in my opinion, are landscapes with mountains.
So here’s a simplified mountain: two overlapping triangles.
Let’s make a function with it:
Once again, now that we have the function for one mountain, we can add multiple mountains!
This doesn’t look great because the mountains are all the same size, but that’s a problem for a future article.
If you’d like some practice, see what you can do about it!
hint: add a h parameter to mountain
HouseLink to heading
We have methods to draw the sky, a sun, grass, trees, and mountains.
A house would fit well!
This will be our most complex drawing element yet. Let’s construct it step by step:
That’s a very basic house, let’s add a door and a doorknob:
Once you have one house, you can have as many houses as you can fit, with little extra effort!
All togetherLink to heading
We’ve built a library of shapes to use in a painting, now it’s just a matter of drawing the painting we want!
Let’s start by drawing one of each shape, so we know what we’re working with:
Now we can re-use them and lay them out as needed.
It’s not going to win any art competitions, but that’s not the point!
We made a small project with some complexity, out of simple building blocks, thanks to functions.
ConclusionLink to heading
Functions are sequences of instructions, that we can label and reuse.
They are smaller programs (e.g. drawing only a house) inside our bigger program (e.g. drawing the whole painting), that help us keep our code easier to write, understand, and modify.
What we’ve been working with isn’t a “dumbed down” version of functions. This is what it looks like in “real” code too!
Our instructions have exclusively been about drawing rectangles, circles, triangles, and other groups of them, e.g. door(x, y), but our program is by all means a real program, these are real instructions that come from a library of basic shapes.
What next?Link to heading
You have now understood the concept of functions, which is the important part.
If this was new to you, I recommend you take some time to internalize the concept. Use the editor below and make your own unique painting!
I’m working on new articles so you can learn about loops with the same setup, hold tight!
In the meantime, you can have a look at these (more advanced) resources: