Skip to content

Latest commit

 

History

History
250 lines (159 loc) · 9.12 KB

chapter_1.livemd

File metadata and controls

250 lines (159 loc) · 9.12 KB

Chapter 1: Hello World

Before we begin..

Welcome!

The document you are reading is a "Livebook", a kind of notebook that can be edited and used by multiple people and contain dynamic content like code, charts, buttons, videos and much more.

The facilitator should have demonstrated how to get it running on your computer and the basics of using the tool.

First steps

It is an ancient tradition amongst programmers that the first program one writes is called "Hello World". That's because all the program does is to print those two words on the screen.

We will do the same as our first exercise.

Exercise 1.1: printing Hello World

Click inside the black box below and type Hello world!.

Then press the keys Ctrl + Enter (on Windows) or Command + Enter (on Mac) to run the program.

Hello World!

If you did that correctly, you should see a red notice and an error.

That's because programming languages treat text differently than human languages. Anything we type into the black box is assumed to be code instructions. And those two words don't match any existing instructions, so it leads to an error.

Let's instead try to tell the computer that these are in fact just two ordinary words and not a piece of code. We can do that, by wrapping the two words in double quotes (").

Try it below and run the code:

This time there should be no error, instead you should see the same words repeated back at you, now in green text.

Variables

So we know how to type text that the computer can work with. Let's learn how to reuse our text.

We can use a concept called "variables", which exists in all programming languages. (You might remember that word from math class, where they serve a similar purpose.)

You can think of variables as containers or boxes, that can store other things. Things like text, numbers, images, or almost anything else. By putting a thing in labeled box, we make it easier to find and reuse later.

Say we want to store the name of our user in a variable, so we can greet them when they run our program.

To create a variable, we first have to come up with a good label for it. In this case, name seems pretty approriate for storing someones name!
(Note how name is not in quotes because it is a variable and not a piece of text!)

After the label, we add a = (equals symbol), followed by the thing we want to store. In this case it is the name of our user, "Grace".

So by using an equal symbol, we are telling the computer that these two things are equivalent, ie. they refer to the same thing. So the next time it sees name, it will look it up in its memory and gives us the content inside, which is "Grace".

Here's how that looks:

name = "Grace"

Once we set a value for a variable, we can get the stored contents back by calling the variable itself. Click inside the code block below and press Ctrl+Enter to run it.

name

Mixing text and variables

Now we know how to store and access the name. But what if we want to combine some text with a variable?

For example, outputting "Hello Grace" using our name variable. How can we achieve this?

We saw in the first exercise that we need to use double quotes ("") to tell the computer that we are giving it ordinary text and not code instructions. What happens if you use the variable name within double quotes? Try it out below.

"Hello name"

This will just treat the word name as regular text, and not as code, therefore outputting "Hello name" instead of our desired "Hello Grace".

Elixir has a way to tell the computer that a variable needs to be replaced instead of treated as part of the text. The variable name can be wrapped inside curly braces preceded by a hashtag symbol: #{variable}.

Try to run the example below:

"Hello #{name}"

This way, the output contains the original text and the variable placeholder has been replaced by the contents. In this case it is "Grace", but it could also have been "Peter" or "Ben" or whatever we decided to put inside the variable when we created it.

Exercise 1.2: using variables within a text

Write a small text where you can say your name and age, using variables for the name and the age.

Functions

We would like to make programs that can do more than just printing text. To do that we need a way to structure and organize our code.

Functions in Elixir are a basic concept that helps us group a set of instructions together.

They work similarly to functions in math: they take some input, do something with the input, and return an ouput.

We will create and use one function for each action that we want our program to do.

Functions are defined with the def keyword (short for define), it is shown in purple in the code box.

Functions have a unique name that allows us to identify and reuse them, shown in blue.

The name of the function is generally written in what is called snake_case, which means words connected by underscores. (So "My beautiful function" would usually be written as my_beautiful_function)

Right after the name we chose, we write the word do, to indiciate that anything that follows is what the function should do.

Then we can define any instructions on the next lines.

Once we are done, we use the word end to indicate that we have reached the end of the function and no more work should be done.

def my_function_name do
  "Hello Grace"
end

Elixir has also another type of function, but we will not talk about it at this point. As you might have noticed if you tried to run the above code, this will error. That's because a function needs to have a home. It needs to be placed inside what we call a module.

We can use modules to organize our functions. A module can contain one or more functions.

A module is opened with the defmodule keyword, followed by a name of our choosing, and then a do...end block containing our actual function.

The module name is generally written in what it is called "CamelCase", meaning no spaces and the first letter of each word capitalized. (So "My beautiful module" would usually be written as MyBeatifulModule)

defmodule MyModuleName do
  def my_function_name do
  end
end

Once we have a function within a module, we could place our previous istruction in the function:

defmodule GraceGreeter do
  def greet_grace do
    "Hello Grace"
  end
end

How can we print the text after this step? We do that by calling the function, using its name. And because the function is placed within the module, we need to tell the computer where the function is located and what it is called. So we call the module name, and chain the function name to it with a dot:

GraceGreeter.greet_grace()

We are however not yet done. How does it work if we want to be able to greet different people than Grace? We can combine the use of a variable that we saw above with our function. How will that look like?

defmodule PersonalGreeter do
  def greet do
    "Hello #{name}"
  end
end

This gives us an error. Lets try to understand what is going on. The compiler complains that the variable name is undefined. What does this mean? In our previous example, we had given our name variable a value. Now, in our new implementation with a module and a function, we are not giving the name variable a value, so the computer does not know what to print for name. How can we give a value to our variable used inside a function? Naturally, we could extend our code and give the variable a value:

defmodule NewGreeter do
  def greet do
    name = "Leia"
    "Hello #{name}"
  end
end

But what is the issue with this? You can probably spot the issue if you run this code as we learnt above:

NewGreeter.greet()

What is the issue? We are using a variable, but this variable will always give us the same output. So, how can we use a module and a function to greet different people? We need to somehow be able to give the function the value we want it to use when we run the code. We do this using something called parameters. Parameters are used in two places:

  • in the function definition:
defmodule SmarterGreeter do
  def greet(name) do
    "Hello #{name}"
  end
end

where we define the variable name we are going to use

  • in the function call:
SmarterGreeter.greet("Luke")

where we tell the computer which value to use for the variable name.

Exercise 1.3: functions and modules

Write a module with functions that greet you in english and danish, giving you the following output and taking as inputs the name and the language of the greeting.

"Hej Grace"
"Hello Grace"

TODO: Function that does something more interesting

Bonus

Calling built-in functions

"Hello #{name}, your name is #{String.length(name)} characters long"
defmodule LoudGreeter do
  def shout(name) do
    "HELLO #{String.upcase(name)}, CAN YOU HEAR ME?!"
  end
end
LoudGreeter.shout(name)