Awesome! I’m so glad you’ve chosen Verse for learning to program. Coding is (or can be, at least) one of the most fun hobbies/careers out there, so I hope I can impart some of that joy in these tutorials.

If you get stuck or have any questions as you work through the examples and exercises, please post @VerseCode on Facebook and I’ll do my best to help you out.

Supported Platforms

Before we get started, let’s make sure you have the right setup. Currently, Verse works on macOS 10.11 (El Capitan) or newer (it might work on Windows and Linux, but I haven’t tested it).

Additionally, you’ll need the latest version of one of these web browsers:

Support for more platforms (including mobile) is coming soon, but for now it’s just these. If there’s a particular OS or browser you think I should support, just post on the Verse Facebook page. If enough people ask for it, I’ll figure out a way to make it work.

Hello, World!

Okay, you’ve installed an awesome web browser and you’re ready to code! Right-click this link and open it in a new window to bring up Verse.

Screenshot of a new Verse project with no code in the editor

The white area—the left half of the screen, basically—is the editor, the place where we’ll type our code. When the code runs, it will display things on the right half of the screen.

We’ll start with the classic introduction to coding: the “Hello, World” program, which just makes the text “Hello, World” (or whatever message we want) appear on the screen.

To start, click the big “START” button. Then type the code below into the editor. To type the {} characters (programmers call them “curly braces”), hold shift and use the keys just to the right of P (assuming you have an American keyboard). Note that when you type an opening parenthesis ( or curly brace }, a matching ) or } will be inserted automatically.

define({
})

This line of code forms the backbone of our program. All our other code will go between the curly braces { ... }.

Once you’ve typed that out, the LOAD button at the top of the screen should be bright blue-green. This indicates that the computer understood what you typed and was able to load your code into its machinery successfully. If the button is yellow instead, check your work and make sure it matches the example. Computers are very picky about the code they’ll accept.

Now let’s define a function that will put our “Hello, World” message on the screen. A function is a list of instructions for the computer that tell it how to perform some task and give us back the result. If you think of the computer as a restaurant cook, a function is like a recipe that tells it how to make one of the items on the menu.

To define a function, we first have to give it a name. Most of the time when we create a function, we can choose any name we want as long as it contains only letters and numbers (no spaces or punctuation). However, we’re going to give this function a very specific name: displayText. The name displayText tells Verse to use this function to determine what text will be shown on the screen when the program runs.

After the name of the function, we need to put a pair of parentheses () and a pair of curly braces {}.

define({
  displayText() {
  }
})

When your code looks like the example above, you should see the green LOAD button again. Again, if it’s yellow, check your work for mistakes.

If nothing you type seems to give you the green light at this point, just copy-paste the example code into the editor.

If you’ve copy-pasted it and it still doesn’t work, please message @VerseCode on Facebook and let me know.

We’re almost done! We have a function, but it doesn’t do anything. We just need to add an instruction, or statement, between the curly braces. The computer will follow this instruction when it runs the displayText function.

define({
  displayText() {
    return 'Hello, World!'
  }
})

Here, we’re using the return keyword to hand off the text 'Hello, World!' to the computer. The text will then get drawn on the screen. We surround the text in single quotes so the computer knows where it begins and ends.

When you’re done typing, you should once again see the green LOAD light. And at this point, you should also see the text Hello, World! on the right side of the screen.

It works!

A screenshot of the running Hello World program

Experiments

Now that you’ve got a working chunk of code, I encourage you to play around with changing it to see what works and what doesn’t.

  1. Try changing the function name displayText to something else. What happens?
  2. The quotes around ‘Hello, World!’ tell the computer exactly where the text starts and ends. Try changing ‘Hello, World!’ to ‘Doesn’t work’. What do you think is causing the problem?
  3. Change the text ‘Hello, World!’ to whatever message you want.
  4. Try deleting the spaces and indentation from the code. Which spaces are necessary and which ones aren’t?
  5. Try adding more spaces between the words and punctuation. Are there places where adding spaces will break the code?
  6. What happens if you delete the return keyword?

Review

Congratulations! You’ve written your first program and taken your first steps into the world of Verse! Let’s review the key things we’ve learned:

Shouting at the World

Our program is currently rather uninteresting. Let’s see if we can make it automatically transform our “Hello, World” greeting into ALL CAPS SO IT LOOKS LIKE IT’S SHOUTING.

define({
  displayText() {
    return uppercase('Hello, World!')
  }
})

Here we see our first example of how to call, or use, a function in JavaScript. We’re calling a function named uppercase by mentioning its name and following it with a pair of parentheses. Between the parentheses, we feed in some data: the text ‘Hello, World!’. The function processes the text and gives us back the result, which we return so it is displayed on the screen.

Returning to our functions-are-recipes metaphor: calling a function is like shouting to the cook “one order of fried applesauce for table 6, please!”. Except instead, we’re asking for “one order of uppercase hello world!”

Just to illustrate this, here’s how we’d ask the computer for fried applesauce:

define({
  displayText() {
    return fried('applesauce')
  }
})

And this would totally work if our computer knew how to fry text. But there’s no function named fried, so this program will give us an error if we try to run it.

You may be wondering where the uppercase function comes from. In other words, why does uppercase work but fried doesn’t? The answer is pretty boring: the uppercase function is just built into Verse. A list of built-in functions and how to use them is available here will be available once I get my act together.

The Beauty of Functions

If you just look at the output of our little program, it’s exactly the same as if we’d written

define({
  displayText() {
    return 'HELLO, WORLD!'
  }
})

That’s because a function call like uppercase('Hello, World!') stands in for the result of the function. You can replace one with the other and the output of the program won’t change. The five-dollar term for this is referential transparency (and yes, you can totally impress people by mentioning referential transparency at parties).

Of course, you may be wondering: why not just replace the function call with the uppercased result? It would be a lot simpler! But then we would be doing work that the computer can do much more quickly and accurately. The nice thing about calling uppercase is that we can now convert any text we want to all-caps, just by copy-pasting it into our program. Try it with this paragraph! Just make sure you have quotes around the text so the computer knows where it begins and ends.

At this point, you may be starting to sense that functions have a beautiful kind of usefulness. Once you know the name of a function and what it does, it’s like having a new skill that you can use everywhere. A good cook knows not only how to make fried('applesauce'), but fried('lamb chops') or fried('crème brûlée') too. Just as frying is a process that can be applied to almost anything, uppercasing is a process that can be applied to any text. In programming, this type of simple process that can be applied to an infinity of different objects is called an abstraction.

Talking Backwards

Let’s try out another function that’s built into Verse: reverse, which takes a string of text and returns a backwards version of it, so hello becomes olleh.

define({
  displayText() {
    return reverse('Hello, World!')
  }
})

Experiments

  1. Try replacing “Hello, World!” in the program above with a message of your choice.
  2. A word or phrase that is spelled the same forwards and backwards is called a palindrome. Use the reverse function to demonstrate that tacocat is a palindrome. Or try this epitaph for Napoleon: able was I ere I saw elba.
  3. Try writing a program that outputs the reversed, uppercase version of a string: that is, if you paste in the text ‘hello world’ it should output ‘DLROW OLLEH’. Hint: remember that a function call stands in for the result of the function.
  4. It seems like reverse(uppercase('hello')) and uppercase(reverse('hello')) always produce the same output. Why do you think this is?
  5. What do you expect reverse(reverse('hello')) to output? Try it!

Mirror Text

In this lesson, we’ll deepen our knowledge of how to process and transform text. We’ll write a program that, given a word or phrase, creates a palindrome by “mirroring” it, like this:

"hello" -> "helloolleh"
"rats live on " -> "rats live on  no evil star"

We already know how to reverse text, so we’re halfway there! The tricky bit is, how do we output both the original text (the first half of the palindrome) and the reversed version (the second half)?

Let’s start simple by hardcoding the reversed text, rather than using reverse to generate it. We can glue the forward and reversed text together using the + operator.

define({
  displayText() {
    return 'hello' + 'olleh'
  }
})

Run the program (if it’s not running already); at this point, it should output helloolleh.

Now, using the principle of referential transparency and our knowledge of how reverse works, we can replace 'olleh' with reverse('hello'):

define({
  displayText() {
    return 'hello' + reverse('hello')
  }
})

When you’re done making that change, the output should still be helloolleh. Make sure you’re still seeing the green LOAD light too; if it’s yellow, the output you’re seeing is likely from the previous version of the program, with the hardcoded text.

Using Variables

There’s one more change we can make to improve this code. The text 'hello' is repeated twice, so if we want our program to output a different palindrome, we have to change it in two places, e.g.

define({
  displayText() {
    return 'rats live on ' + reverse('rats live on ')
  }
})

That’s a lot of typing! Worse, having the text in two places makes it less clear that our program is designed to output a palindrome. If we changed just one of the places, the output would no longer be a palindrome:

define({
  displayText() {
    return 'rats live on ' + reverse('hello')
  }
})

The way we can fix this is by using a variable. Variables are one of the most useful concepts in programming. A variable is like a container where you can store information (like text and numbers) that you aren’t going to use right away but want to save for later.

Let’s add a variable called forwardsText to our program to store the text we’re going to reverse. The keyword let tells the computer that we’re creating a new variable, and the = operator puts the value to its right into the variable.

define({
  displayText() {
    let forwardsText = 'hello'
    return 'hello' + reverse('hello')
  }
})

You can read this in your head as “let forwards text be hello”. Read it as dramatically as you like! It has the authority of an autocratic proclamation. Rest assured that now and henceforth, forwardsText is 'hello'.

We can use our newly minted variable in our return statement, just by replacing the hardcoded value 'hello' with the name of our variable. Like function calls, this replacement follows the principle of referential transparency: because we’re replacing the value 'hello' with a variable that’s storing the text 'hello', the output of our program won’t change.

define({
  displayText() {
    let forwardsText = 'hello'
    return forwardsText + reverse(forwardsText)
  }
})

Now we can easily change our program to output any text we want!

define({
  displayText() {
    let forwardsText = 'rats live on '
    return forwardsText + reverse(forwardsText)
  }
})

Statements in Functions

So far, we’ve only seen functions with one step, or statement—and that statement has always started with return. Now that we’re using variables, we’ve introduced a second type of statement—the let statement—and now we have to understand how the computer interprets functions with multiple statements.

Fortunately, it’s not very complicated: statements within a function run in top-down order. When running our program, the computer starts with the let statement, and only once the variable has been created and the text stored does it move on to the return. Because of this strict ordering, the let statement must come before the return statement—otherwise, the variable won’t exist when we try to use it, and our program will crash.

Clean Code Tip: Naming Variables

In this tutorial we named our variable forwardsText, but we could have named it anything we wanted. (There are some restrictions on variable names, though: they can only contain uppercase and lowercase letters, numbers, and the symbols $ and _, and they can’t start with a number.) With this awesome power and freedom comes the responsibility to choose good names for our variables.

In general, it’s good for variable names to be:

Other names I considered for this variable include:

You definitely don’t have to think about every variable name this much, but it’s good to get in the habit of choosing names deliberately. When you start writing more complex code, good variable names will make the difference between manageable and incomprehensible.

Experiments

  1. Try changing the value stored in the forwardsText variable. Can you invent a new palindrome that’s an actual phrase or sentence in English (or any language of your choice)?
  2. Change the variable name following let to broken (don’t change the places where the variable is used). What error do you see?
  3. Change the variable name to whatever you want. Update the places where it’s used, too, so the program works.
  4. What happens if you move the return statement up one line, so it comes before the let? For example:

    define({
      displayText() {
        return forwardsText + reverse(forwardsText)
        let forwardsText = 'hello'
      }
    })
    
  5. Try to change the program so it outputs an “inside-out” palindrome—that is, if the text stored in the variable is 'hello', it should output ollehhello.

Making an Interactive Program

The programs we’ve written so far have an unfortunate shortcoming: in order to make them process different text, we have to change their code. That makes them next to useless for people who don’t know how to program.

We need to make our programs interactive so anyone can use them. For example, it would be great if our “reverse” program could prompt the user to type in the text they want to reverse, and then show them the reversed output.

In Verse, we create interactive programs by defining a special function called run. We’ll learn more about how this function works in later tutorials; for now just copy-paste the code below.

define({
  process(input) {
    return reverse(input)
  },

  *run() {
    let input = yield waitForInput()
    yield log(process(input))
    yield retry(run)
  }
})

Now when you click the “Run” button, you’ll see an input prompt at the bottom of the screen. It looks sort of like this:

> _

Type your name, or any message you like, and then hit the return key. You can type as many messages as you want, hitting return after each one, and the program will echo back the reversed versions.