> For the complete documentation index, see [llms.txt](https://daniel-sokil.gitbook.io/purescript-book/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://daniel-sokil.gitbook.io/purescript-book/text/chapter2.md).

# Getting Started

## Chapter Goals

In this chapter, the goal will be to set up a working PureScript development environment and to write our first PureScript program.

Our first project will be a very simple PureScript library, which will provide a single function that can compute the length of the diagonal in a right-angled triangle.

## Introduction

Here are the tools we will be using to set up our PureScript development environment:

* [`purs`](https://www.purescript.org) - The PureScript compiler itself.
* [`npm`](https://www.npmjs.com) - The Node Package Manager, which will allow us to install the rest of our development tools.
* [`spago`](https://github.com/purescript/spago) - A command-line tool that automates many of the tasks associated with managing PureScript projects.

The rest of the chapter will guide you through installing and configuring these tools.

## Installing PureScript

The recommended approach to installing the PureScript compiler is to download a binary release for your platform from the [PureScript website](https://www.purescript.org).

You should verify that the PureScript compiler executables are available on your path. Try running the PureScript compiler on the command line to verify this:

```
$ purs
```

Other options for installing the PureScript compiler include:

* Via NPM: `npm install -g purescript`.
* Building the compiler from source. Instructions can be found on the PureScript website.

## Installing Tools

If you do not have a working installation of [NodeJS](https://nodejs.org), you should install it. This should also install the `npm` package manager on your system. Make sure you have `npm` installed and available on your path.

Spago is a PureScript build tool and package manager. You will need to install it using `npm`, as follows:

```
$ npm install -g spago
```

This will place the `spago` command-line tools on your path. At this point, you will have all the necessary tools to create your first PureScript project.

## Hello, PureScript!

Let's start out simple. We'll use Spago to compile and run a simple Hello World! program.

Begin by creating a project in an empty directory and use the `spago init` command to initialize the project:

```
$ mkdir my-project
$ cd my-project
$ spago init
Initializing a sample project or migrating an existing one..

$ ls
packages.dhall    spago.dhall    src        test
```

Spago has created a number of directories and configuration files. The `src` directory will contain our source files and the `test` directory will contain any tests we write. The `spago.dhall` file contains the project configuration.

Modify the `src/Main.purs` file to contain the following content:

```haskell
module Main where

import Effect.Console

main = log "Hello, World!"
```

This small sample illustrates a few key ideas:

* Every file begins with a module header. A module name consists of one or more capitalized words separated by dots. In this case, only a single word is used, but `My.First.Module` would be an equally valid module name.
* Modules are imported using their full names, including dots to separate the parts of the module name. Here, we import the `Effect.Console` module, which provides the `log` function.
* The `main` program is defined as a function application. In PureScript, function application is indicated with whitespace separating the function name from its arguments.

Let's build and run this code using the following command:

```
$ spago run
...
Build succeeded.
Hello, World!
```

Congratulations! You just compiled and executed your first PureScript program.

## Compiling for the Browser

Spago can be used to turn our PureScript code into JavaScript suitable for use in the web browser by using the `spago bundle-app` command:

```
$ spago bundle-app
...
Build succeeded.
Bundle succeeded and output file to index.js
```

All the code in the `src` directory, a standard PureScript library known as the *Prelude* and any project dependencies have been compiled to JavaScript. The resulting code is bundled as `index.js` and has also had any unused code removed, a process known as dead-code-elimination. This `index.js` file can now be included in an HTML document. If you try this, you should see the words "Hello, World!" printed to your browser's console.

If you open `index.js`, you should see a few compiled modules which look like this:

```javascript
// Generated by purs bundle 0.13.3
var PS = {};
(function(exports) {
  "use strict";

  exports.log = function (s) {
    return function () {
      console.log(s);
      return {};
    };
  };
})(PS["Effect.Console"] = PS["Effect.Console"] || {});
(function($PS) {
  // Generated by purs version 0.13.3
  "use strict";
  $PS["Effect.Console"] = $PS["Effect.Console"] || {};
  var exports = $PS["Effect.Console"];
  var $foreign = $PS["Effect.Console"];
  exports["log"] = $foreign.log;
})(PS);
(function($PS) {
  // Generated by purs version 0.13.3
  "use strict";
  $PS["Main"] = $PS["Main"] || {};
  var exports = $PS["Main"];
  var Effect_Console = $PS["Effect.Console"];
  var main = Effect_Console.log("Hello, World!");
  exports["main"] = main;
})(PS);
PS["Main"].main();
```

This illustrates a few points about the way the PureScript compiler generates JavaScript code:

* Every module gets turned into an object, created by a wrapper function, which contains the module's exported members.
* PureScript tries to preserve the names of variables wherever possible.
* Function applications in PureScript get turned into function applications in JavaScript.
* The main method is run after all modules have been defined and is generated as a simple method call with no arguments.
* PureScript code does not rely on any runtime libraries. All of the code that is generated by the compiler originated in a PureScript module somewhere which your code depended on.

These points are important since they mean that PureScript generates simple, understandable code. The code generation process, in general, is quite a shallow transformation. It takes relatively little understanding of the language to predict what JavaScript code will be generated for a particular input.

## Compiling CommonJS Modules

Spago can also be used to generate CommonJS modules from PureScript code. This can be useful when using NodeJS, or just when developing a larger project which uses CommonJS modules to break code into smaller components.

To build CommonJS modules, use the `spago build` command:

```
$ spago build
...
Build succeeded.
```

The generated modules will be placed in the `output` directory by default. Each PureScript module will be compiled to its own CommonJS module, in its own subdirectory.

## Tracking Dependencies

To write the `diagonal` function (the goal of this chapter), we will need to be able to compute square roots. The `math` package contains type definitions for functions defined on the JavaScript `Math` object, so let's install it:

```
$ spago install math
```

The `math` library sources should now be available in the `.spago/math/{version}/` subdirectory, and will be included when you compile your project.

## Computing Diagonals

Let's write the `diagonal` function, which will be an example of using a function from an external library.

First, import the `Math` module by adding the following line at the top of the `src/Main.purs` file:

```haskell
import Math (sqrt)
```

It's also necessary to import the `Prelude` module, which defines very basic operations such as numeric addition and multiplication:

```haskell
import Prelude
```

Now define the `diagonal` function as follows:

```haskell
diagonal w h = sqrt (w * w + h * h)
```

Note that there is no need to define a type for our function. The compiler can infer that `diagonal` is a function that takes two numbers and returns a number. In general, however, it is a good practice to provide type annotations as a form of documentation.

Let's also modify the `main` function to use the new `diagonal` function:

```haskell
main = logShow (diagonal 3.0 4.0)
```

Now compile and run the project again, using `spago run`:

```
$ spago run
...
Build succeeded.
5.0
```

## Testing Code Using the Interactive Mode

The PureScript compiler also ships with an interactive REPL called PSCi. This can be very useful for testing your code and experimenting with new ideas. Let's use PSCi to test the `diagonal` function.

Spago can load source modules into PSCi automatically, via the `spago repl` command:

```
$ spago repl
>
```

You can type `:?` to see a list of commands:

```
> :?
The following commands are available:

    :?                        Show this help menu
    :quit                     Quit PSCi
    :reload                   Reload all imported modules while discarding bindings
    :clear                    Discard all imported modules and declared bindings
    :browse      <module>     See all functions in <module>
    :type        <expr>       Show the type of <expr>
    :kind        <type>       Show the kind of <type>
    :show        import       Show all imported modules
    :show        loaded       Show all loaded modules
    :show        print        Show the repl's current printing function
    :paste       paste        Enter multiple lines, terminated by ^D
    :complete    <prefix>     Show completions for <prefix> as if pressing tab
    :print       <fn>         Set the repl's printing function to <fn> (which must be fully qualified)
```

By pressing the Tab key, you should be able to see a list of all functions available in your own code, as well as any project dependencies and the Prelude modules.

Start by importing the `Prelude` module:

```
> import Prelude
```

Try evaluating a few expressions now:

```
> 1 + 2
3

> "Hello, " <> "World!"
"Hello, World!"
```

Let's try out our new `diagonal` function in PSCi:

```
> import Main
> diagonal 5.0 12.0

13.0
```

You can also use PSCi to define functions:

```
> double x = x * 2

> double 10
20
```

Don't worry if the syntax of these examples is unclear right now - it will make more sense as you read through the book.

Finally, you can check the type of an expression by using the `:type` command:

```
> :type true
Boolean

> :type [1, 2, 3]
Array Int
```

Try out the interactive mode now. If you get stuck at any point, simply use the Clear command `:clear` to unload any modules which may be compiled in memory.

## Exercises

1. (Easy) Use the `pi` constant, which is defined in the `Math` module, to write a function `circleArea` which computes the area of a circle with a given radius. Test your function using PSCi (*Hint*: don't forget to import `pi` by modifying the `import Math` statement).
2. (Medium) Use `spago install` to install the `globals` package as a dependency. Test out its functions in PSCi (*Hint*: you can use the `:browse` command in PSCi to browse the contents of a module; try `:browse Global` and compare what PSCi tells you to what you find in [**Pursuit**](https://pursuit.purescript.org/packages/purescript-globals/4.1.0/docs/Global)).

## Conclusion

In this chapter, we set up a simple PureScript project using the Spago tool.

We also wrote our first PureScript function and a JavaScript program which could be compiled and executed either in the browser or in NodeJS.

We will use this development setup in the following chapters to compile, debug and test our code, so you should make sure that you are comfortable with the tools and techniques involved.
