You’ve learned how to define (or “create”) a machine and how to tell it to do something. But just like our coffee machine needs beans to create coffee, most machines you write will need some input.

How do you provide this input? You need to give it to the machine.

But that’s not enough. The machine needs to accept the input. It needs some hole, container, area labeled “place your coffee beans here and nowhere else!”

As such, there are two steps to making a machine accept input.

  • When defining the machine, also define what it wants
  • When calling it, also give it what it needs

Define what it wants

Let’s start with one input first. That’s the simplest.

To make a machine want one input, add wants NAME to the definition

As always, you can invent the name yourself. Make it something descriptive and clear.

Click to unfold (and show solution)
Results

This machine squares any number you give it, as you’d expect.

Give it what it needs

Now you know: “this machine wants one input”. By the name, you also know it should be a number. Coding this way is like telling your future self what to do.

To give a machine input, use give VALUE to MACHINE

Icon to signal a Data Transformation.
Name & Value
 => 
Value
Click to unfold (and show solution)
Results

Magic! It calculated the square of 5!

Try it with different values. Give your machine whatever you want. Once you’re ready, we can move to multiple inputs.

Multiple inputs

All the rules stay the same. It’s just that you need some way to separate the inputs. To tell the computer where one input stops and another starts.

As usual, I chose to write this like a sentence.

To give a list of inputs, separate them with and

Icon to signal a Data Transformation.
Name & Values
 => 
Value
Click to unfold (and show solution)
Results

Magic again! You can give as many inputs as you like.

Try it. Create something that adds 3 numbers. Or maybe a more complex machine.

Of course, this becomes a bit annoying to type if you give lots of inputs. That’s why you want to keep your machines as small and simple as possible. Once you start giving it 3, 4, or more inputs … you should split it into smaller machines.

Remark

The inputs a function wants are called parameters. The actual values you give it are called arguments.

In dynamic languages (like mine), you can be loose with it. You can give too few arguments, or too many, and it won’t complain. (It’s not recommended, but you can do it.) More strict languages require you to give exactly the inputs specified and nothing else.

Stopping early

So far, a machine will run its whole process ( = all its code) and output the end result. You might not want that.

Remember the stop and skip keywords I introduced in Loops? I explained how you can use them for “guard clauses”: to exit early if you don’t want code to execute.

Yes, a similar thing exists for machines! You can tell a machine to immediately stop working at any point.

To stop a machine, call unplug or output

I noticed some people understood the first keyword, others the second, so I allowed them both. But they are identical: you immediately unplug the machine. Whatever its last value was, that’s all you get from it.

Why use this? For the same reason you’d stop or skip a loop. It’s a short and easy way to prevent executing code you don’t want.

Look at the example below. The code becomes quite complex with all the nested statements. (Adding more and more indentation in front of lines!) This is a “very simple” example. If you’re writing real code, this becomes annoying and unreadable quickly.

Click to unfold (and show solution)
Results

Exercise: rewrite

We can rewrite this. Using a machine that stops early.

First, try it yourself. You can modify the code block above, or use the empty one below.

Click to unfold (and show solution)
Results
Click to unfold (and show solution)
Results

Look at that! We now have …

  • A simpler loop
  • A machine we can reuse all across the project
  • Code that is easier to read

Exercises

Logging in

To log into an account, you need to provide two things: a username and a password.

Let’s try to write a (very barebones and unsafe) login system.

  • Create a bag with usernames and passwords
  • Write a machine that accepts these things
  • And only returns true if they match
Icon to signal a Data Transformation.
Machine & Two Strings
 => 
Bool
Click to unfold (and show solution)
Results
Click to unfold (and show solution)
Results

Try different names! Try a wrong password!

Similarly, many websites allow multiple ways to log in. (Using your Google account, your email address, a QR code, whatever.)

It would be annoying to copy-paste the login code for each different type! Instead, they’ll use one machine called login that accepts some input (like a username). Where that username comes from doesn’t matter to the machine—as it shouldn’t! They only have one job: take the input and log that person in.

As such, websites will have one login machine that handles each case. Once written, they don’t need to worry about it anymore.

Mafia

Mafia (or Werewolf) is a popular party game. In it, a few members get a secret role: the mafia (or werewolf). They have to stay alive until the end, secretly killing innocent members of the town.

Let’s say we make a digital version of that.

Given a player name, the machine should tell us whether they are evil or not.

Icon to signal a Data Transformation.
Machine & Two Strings
 => 
Bool
Click to unfold (and show solution)
Results

Below is my solution—one way to do it. Try changing the names or the roles and see if it still works.

Click to unfold (and show solution)
Results

Using machines well

Replacing comments

Machines can replace those dreaded Comments I talked about earlier.

Instead of writing “this code adds two numbers” … turn it into a machine called addTwoNumbers!

Instead of writing “this code saves the highscore” … turn it into a machine called saveHighscore!

Whenever you feel compelled to explain what a piece of code does—don’t. Instead, pull it into its own machine, and give that a descriptive name.

Pure machines

In functional programming, there’s this “ideal” called a pure function. The idea is simple—applying it is harder.

A pure machine does not depend on any external factors. Given the same input, it always gives the same output.

While I’m not a strict person, I’d still recommend trying to adhere to this. Write your machines to be 100% predictable with their data transformation.

It will eliminate maybe the biggest (frustrating) source of errors (for new and experienced programmers alike): your code does something radically different some of the time! And you don’t know why! Weren’t computers supposed to be logical and consistent?

At least 99% of the time, this error is caused by a machine that uses more than just its inputs inside its calculations.

If you do that, using a machine will not improve your code, it will actually make it worse. Because now you’ve created a huge instability, and you’ve “hidden” it inside a machine somewhere.

Most languages know this. Why? Because of something called function scope. Within a function, most languages only allow access to that function’s inputs, and nothing else. If you need input, you have to give it to the machine. It’s not allowed to access any other variables.

So, if a function can access some data, it is said to be “within scope”. All other data is “out of scope”.

I did this as well. But I turned it off for my examples above, to make things simpler. When I turn it back on, the earlier example will error.

Click to unfold (and show solution)
Results

Why? Because the machine has no clue what “roles” is. It was defined outside of the machine, out of its scope. So it has no access to it.

Remark

To fix this, you pass that bag as an input to the machine. This is great, because now your code tells you that it depends on that bag. It has become a pure machine, without hidden dependencies.

Conclusion

As always, it’s about data transformations. You put some data into a machine, it changes it, then you get some other data out of the machine.

That’s all coding is. Changing data into other data, to get beautiful end results.

And machines are the way to do it. Supported by every language. Any moderately complex code project heavily relies on a large set of tiny machines.

Knowing this, you can tackle larger problems. You know how to structure your program.

  • Every time you want to do something
  • Identify what data should go in, and what data should go out
  • Write one machine that does exactly that
  • (Call it when needed, with the right input values.)

This basically concludes this course on programming. You have all the building blocks. You have all the tools, you’ve played with them, you know why or how they are applied.

But I won’t leave you hanging. There’s more I can do to help! These last few chapters are filled with …

  • Lots of practical, real-life examples on how to tackle problems
  • Slightly more advanced syntax or coding ideas
  • And finally, a conclusion that discusses where to go next.
Continue with this course
Support me and this website!

Want to support me?

Buy one of my projects. You get something nice, I get something nice.

Donate through a popular platform using the link below.

Simply giving feedback or spreading the word is also worth a lot.