## Learning objectives

In the previous lesson, we learned how Go implements conditionals via if and else statements. In the main text, our next step was to move on to encounter functions like the pseudocode function `Factorial()`

reproduced below that incorporates a while loop.

Factorial(n) p ← 1 i ← 1 while i ≤ n p ← p · i i ← i + 1 return p

In this lesson, we will see how Go implements while loops.

## Set up

Create a new folder called `loops`

in your `go/src`

directory, and then create a new file within the `go/src/loops`

folder called `main.go`

, which we will edit in this lesson.

In `main.go`

, let us add the following starter code that is comparable to our starter code in previous lessons.

package main import ( "fmt" ) func main() { fmt.Println("Loops.") }

## Code along video

Beneath the video, we provide a detailed summary of the topics and code covered in the code along.

At the bottom of this page, you will have the opportunity to validate your work via auto-graded assessments that evaluate the functions covered in the code along.

Although we strongly suggest completing the code along on your own, you can find completed code from the code along in our course code repository.

## Code along summary

### Implementing a factorial function with a while loop

First, let’s implement `Factorial()`

. We first set two variables `p`

and `i`

equal to 1. The variable `p`

will store the product of integers and is what we will eventually return.

//Factorial takes an integer n as input and returns n! = n*(n-1)*(n-2)*...*2*1 func Factorial(n int) int { p := 1 i := 1 //to be continued return p }

We now encounter a quirk of Go, which is that although it offers support for while loops, it does not have a `while`

keyword. Instead, we will use the keyword `for`

. (We will see soon that `for`

is also used to implement for loops.) Each time through the while loop, we update `p`

to be equal to the product of the current value of `p`

and `i`

, then increase `i`

by one. As with if statements, we place a while loop in brackets, with the final bracket on its own line.

//Factorial takes an integer n as input and returns n! = n*(n-1)*(n-2)*...*2*1 func Factorial(n int) int { p := 1 i := 1 // Go doesn't have a while keyword, and it uses "for" instead for i <= n { p = p*i i = i+1 } return p }

Note that this implementation of `Factorial()`

has the exact same structure as our pseudocode function reproduced at the start of the lesson. Regardless of what language we use, we should be able to use the same structure of a while loop increasing a variable of `i`

by 1 until it reaches `n`

, with a variable `p`

constantly updated as the product `p*i`

.

Let us call `Factorial()`

by appending the following code to `func main()`

.

func main() { fmt.Println("Loops.") n := 5 m := Factorial(n) fmt.Println(m) }

Open a terminal window, and navigate into the folder containing `main.go`

by executing `cd go/src/loops`

. Then compile your code by executing `go build`

and run your code by executing `./loops`

(Mac) or `loops.exe`

(Windows). You should see `120`

printed.

### Handling negative inputs

STOP:Add the line`fmt.Println(Factorial(-100))`

to the end of`main.go`

. Save, compile, and run your code. What is returned? Why?

One way of handling the issues caused by passing a negative input into `Factorial()`

is to check if a negative value is given as input using an if statement; if so, we could use a `panic()`

statement, which will print the error message that it is given as input to the console and then immediately end the program.

//Factorial takes an integer n as input and returns n! = n*(n-1)*(n-2)*...*2*1 func Factorial(n int) int { if n < 0 { // let's handle negative input panic("Error: Negative input given to Factorial()!") } p := 1 i := 1 // Go doesn't have a while keyword, and it uses "for" instead for i <= n { p = p*i i = i+1 } return p }

STOP:Save your code with the updated`Factorial()`

function, then compile and run your code from the terminal. You will see that now, instead of printing`1`

when`fmt.Println(Factorial(-100))`

is executed, the program exits with the error message given to`panic()`

above. You can now safely remove the line`fmt.Println(Factorial(-100))`

from`main.go`

.

Note:You may be wondering why we allow the input`Factorial(0)`

. 0! is traditionally considered to be equal to 1 because, for any other non-negativen,n! = (n+1)!/(n+1). In this case, whennis 0, 0! = 1!/1, and therefore 0! is equal to 1.

### An infinite loop, and a brief musing on programs terminating

Let’s temporarily comment out the line `i=i+1`

from `Factorial()`

, as shown below.

//Factorial takes an integer n as input and returns n! = n*(n-1)*(n-2)*...*2*1 func Factorial(n int) int { if n < 0 { // let's handle negative input panic("Error: Negative input given to Factorial()!") } p := 1 i := 1 // Go doesn't have a while keyword, and it uses "for" instead for i <= n { p = p*i //i = i+1 } return p }

Let’s then compile and run our code using the same `func main()`

as before, reproduced below.

func main() { fmt.Println("Loops.") n := 5 m := Factorial(n) fmt.Println(m) }

When we run this program in the terminal, we see a blinking cursor. The program is running behind the scenes, but it never prints `m`

because it is stuck in an infinite loop within the call to `Factorial(n)`

. program never finishes because it is stuck in an infinite loop!

Note:You can terminate a process in a terminal window using the command`Control+C`

.

As we start to code larger projects, we will see that it is normal for a function or for a program to take a few minutes, a few hours, or even a few days to finish. This means that it is difficult to discern whether the code is still running or hung in an infinite loop. You might wonder if it is possible to write code to provide a quality assurance check of whether a given program is going to terminate. It turns out that this question lies at the dark heart of computer science, and we will return to it in a later chapter.

### Summing the first n integers

Exercise:Write a function`SumFirstNIntegers()`

in Go using a while loop that takes an integer`n`

as input and returns the sum of the first`n`

positive integers. As always, we suggest starting on the level of planning in pseudocode.

Our `SumFirstNIntegers()`

function is shown below. Note that the structure of this function is very similar to the structure of `Factorial()`

. The only difference is that instead of introducing a variable `p`

to store our growing product (which is declared to be equal to 1 and is updated via the command `p=p*i`

each time through the loop), we use a variable `sum`

(which is declared to be equal to 0 and is updated via the command `sum=sum+i`

each time through the loop). We have also added a `panic()`

statement to handle negative inputs.

//SumFirstNIntegers takes an integer n as input and returns the sum of the first n positive integers func SumFirstNIntegers(n int) int { if n < 0 { panic("Error: negative integer given to SumFirstNIntegers") } sum := 0 var i int = 1 for i <= n { sum = sum+i i = i+1 } return sum }

### Syntax shortcuts for incrementing or updating a variable

We make an aside to introduce a few syntactical shorthands for changing the values of variables. **Incrementing** a variable, or adding one to it, is so common that language designers have built in a special notation for it. Instead of `i = i+1`

for incrementing i, we can use the shorthand `i++`

. We also have the shorthand `i--`

to denote `i = i-1`

.

Note:The popular programming language C++ is an homage to this shorthand incrementation syntax, as C++ was designed as the successor of the earlier programming language C.

The update `sum = sum+i`

is very common as well. We would like to update a variable (`sum`

) by adding something (the current value of `i`

) to the variable’s current value. This statement can be written using the shorthand `sum += i`

.

Using these two syntax shorthand tricks, we can update `SumFirstNIntegers()`

as follows.

//SumFirstNIntegers takes an integer n as input and returns the sum of the first n positive integers func SumFirstNIntegers(n int) int { if n < 0 { panic("Error: negative integer given to SumFirstNIntegers") } sum := 0 var i int = 1 for i <= n { sum += i // same as sum = sum+i i++ // same as i = i+1 } return sum }

As you might imagine, Go also supports shorthand variable updates corresponding to subtraction, multiplication, and division, as summarized below.

`sum -= i`

is equivalent to`sum = sum - i`

;`sum /= i`

is equivalent to`sum = sum / i`

;`sum *= i`

is equivalent to`sum = sum * i`

.

If all these shorthand variable updates look alien to you, that is fine! They may take some getting used to, and in the meantime there is nothing wrong with writing `i = i+1`

or `sum = sum + i`

.

STOP:Use shorthand variable updates to update two lines of`Factorial()`

.

### Looking ahead to Euclid’s GCD algorithm

Before continuing, we point out that you now know enough about loops in Go to implement Euclid’s GCD algorithm. The pseudocode for `EuclidGCD()`

is reproduced below if you would like to give it a shot. Otherwise, we will soon return to show how to implement this algorithm after we discuss how to implement for loops.

EuclidGCD(a,b) while a ≠ b if a > b a ← a − b else b ← b − a return a

## Check your work from the code along

We provide autograders in the window below (or via a direct link) allowing you to check your work for the following functions:

`Factorial()`

`SumFirstNIntegers()`