## File: README.md

&nbsp;

Gleam is a friendly language for building type-safe systems that scale! For more
information see [the website](https://gleam.run).

## Support Gleam!

Gleam is not owned by a corporation, instead it is kindly supported by its
sponsors. If you like Gleam please consider [sponsoring the project or members
of the core team](https://gleam.run/sponsor).

Thank you so much! 💖

---

## File: compiler-wasm/README.md

# Compiler WASM

```sh
# Install the build tool with cargo or brew etc
cargo install wasm-pack

# Build the wasm library
wasm-pack build --release --target web

# Make a tarball to attach to a release
tar -C pkg/ -czvf gleam-v1.1.0-browser.tar.gz .
```

---

## File: docs/compiler/README.md

# Compiler documentation

Hello! Welcome to the documentation for the Gleam compiler. I hope you have fun
with the project!


* [Project structure](#project-structure)
* [Compilation flow](#compilation-flow)
* [Testing](#testing)
	* [Running the tests](#running-the-tests)
	* [Snapshot testing](#snapshot-testing)




## <a name='Projectstructure'></a>Project structure

The project is made up of several Rust crates (projects):

- `compiler-core`: This project parses, analyses, and compiles Gleam projects.
  It is entirely pure and has no IO so that is provided by the other Rust crates
  that wrap this one.
- `language-server`: This project contains code for the Gleam language server,
  including autocomplete, code actions, hover and other features.
- `compiler-cli`: A command line interface that wraps the core compiler and
  language server, providing IO to files and to the console.
- `compiler-wasm`: A JavaScript interface to the core compiler via web assembly.
  Suitable for running in a web browser.

In addition to the Rust code there are these components:

- `Makefile`: A makefile that defines shortcut commands for common tasks when
  working in the Gleam codebase. Run `make help` to view them.
- `test`: A collection of (mostly) Gleam projects that serve as integration tests for the
  compiler.
- `deny.toml`: Configuration for the `cargo-deny` tool which is used to ensure
  that the Rust libraries the compiler depends on adhere to our expectations.
- `containers`: A collection of docker-files used to produce OCI containers for
  each Gleam release.
- `.github/workflows`: GitHub Actions workflow definitions, used to build, test,
  and release new versions of the project.
- `docs`: You're looking at it pal.

## <a name='Compilationflow'></a>Compilation flow

The process for compiling Gleam modules within the compiler looks roughly like
this:

```txt
  Gleam source code       .cache binaries
          ▼                         ▼
┌────────────────────┐ ┌───────────────────────┐
│       Parser       │ │ Metadata deserializer │
└────────────────────┘ └───────────────────────┘
          │                         │
      Untyped AST            Module metadata
          └─────────┐   ┌────────┘     │
                    ▼   ▼              │
           ┌─────────────────────┐     │
           │  Dependency sorter  │     │
           └─────────────────────┘     │
                      │                │
                 Untyped AST           │
              (sorted by deps)         │
                      ▼                │
            ┌───────────────────┐      │
            │   Type checker    │◄─────┘
            └───────────────────┘
                      │
          ┌────── Typed AST ──────┐
          ▼                       ▼
┌────────────────────┐ ┌─────────────────────┐
│   Code generator   │ │ Metadata serializer │
└────────────────────┘ └─────────────────────┘
          │                       │
          │                       ▼
 Erlang or JavaScript   .cache binaries
   printing algebra
          ▼
┌────────────────────┐
│   Pretty printer   │
└────────────────────┘
          │
          ▼
 Erlang or JavaScript
     source code
```

## <a name='Testing'></a>Testing

We like automated tests! They're a great way to verify that the compiler is
doing what we expect it do as we make changes.

### <a name='Runningthetests'></a>Running the tests

- `make test`: Run all the tests. Worth doing before committing any changes.
- `make test-watch`: Run the Rust unit tests when files are saved.
- `make language-test`: Run the cross-platform language integration tests in
  `test/language`.
- `make language-test-watch`: Run said tests when files are saved.
- `make javascript-prelude-test`: Run the unit tests for the JavaScript code
  that implements the Gleam prelude when compiling to JavaScript.
- `make javascript-prelude-test-watch`: Run said tests when files are saved.

The `*-watch` commands require the [`watchexec`][watchexec] program to be
installed.

### <a name='Snapshottesting'></a>Snapshot testing

The compiler makes heavy use of snapshot testing using the
[`cargo-insta`][cargo-insta] tool.

[cargo-insta]: https://github.com/mitsuhiko/insta
[watchexec]: https://github.com/watchexec/watchexec

If you're not familiar with snapshot testing instead of writing an input and an
expected output (as in normal example based tests) you write only the input. The
snapshot testing tool can then be used to mark any new outputs as accepted and
saved into the repository as snap files. If an output for one of the tests
changes then it is considered a failed test and the programmer has the option to
either reject the new version (as it is an incorrect result) or accept it as the
new correct output.

This style of testing saves us huge amounts of time as manually updating all the
expected output when we make changes to the output format of the compiler or
error messaging is time-consuming and very dull. With snapshot testing it takes
seconds.

```sh
# Run the tests
make test

# Interactively verify changes to the snapshots
cargo insta review
```

---

## File: docs/annoyances.md

# Annoyances

This document contains a list of issues and annoyances that we have writing
Gleam code today, so that we can devise solutions to them in future.

There are other annoyances that have known solutions that are yet to be
implemented. These are tracked in the Gleam issue tracker instead.

## Bundling compiled JavaScript is non-obvious

## Cannot shift repeated work to compile or initialise time

For example, regex compilation.

## JavaScript custom type representation could be faster

There's performance improvements to be had. Would would be optimal?

---

## File: docs/runtime-errors.md

# Runtime errors

There are several runtime errors that Gleam code can throw. This documentation
lists them and their runtime properties.

On Erlang runtime errors are Erlang maps thrown with `erlang:error/1`, having at
least these properties:

| Key         | Type   | Value                                       |
| ---         | ----   | -----                                       |
| gleam_error | Atom   | See individual errors                       |
| message     | String | See individual errors                       |
| file        | String | A path to the original source file location |
| module      | String | The module the error occurred in            |
| function    | String | The function the error occurred in          |
| line        | Int    | The line number the error occurred on       |

On JavaScript runtime errors are instances of the JavaScript `Error` class,
having at least these properties added to them:

| Key         | Type   | Value                                 |
| ---         | ----   | -----                                 |
| gleam_error | String | See individual errors                 |
| message     | String | See individual errors                 |
| module      | String | The module the error occurred in      |
| function    | String | The function the error occurred in    |
| line        | Number | The line number the error occurred on |

## Todo

A panic that indicates that the code has not yet been completed, intended for
use in development.

```gleam
todo
todo as "some message"
```
| Key         | Erlang Value      | JavaScript Value  |
| ---         | ------------      | ----------------  |
| gleam_error | `todo`            | `"todo"`          |
| message     | The given message | The given message |

## Panic

An explicit panic to unconditionally error.

```gleam
panic
panic as "some message"
```
| Key         | Erlang Value      | JavaScript Value  |
| ---         | ------------      | ----------------  |
| gleam_error | `panic`           | `"panic"`         |
| message     | The given message | The given message |

## Let assert

An inexhaustive pattern match, erroring if the pattern does not match.

```gleam
let assert Ok(x) = something()
let assert Error(e) = something() as "This should fail"
```
| Key                  | Erlang Value                                               | JavaScript Value                                          |
| ---                  | ------------                                               | ----------------                                          |
| gleam_error          | `let_assert`                                               | `"let_assert"`                                            |
| message              | The given message                                          | The given message                                         |
| value                | The unmatched value                                        | The unmatched value                                       |
| start                | The byte-index of the start of the `let assert` statement  | The byte-index of the start of the `let assert` statement |
| end                  | The byte-index of the end of the `let assert` statement    | The byte-index of the end of the `let assert` statement   |
| pattern_start        | The byte-index of the start of the asserted pattern        | The byte-index of the start of the asserted pattern       |
| pattern_end          | The byte-index of the end of the asserted pattern          | The byte-index of the end of the asserted pattern         |

## Assert

An assertion of a boolean value.

The error format of `assert` differs based on the expression that is asserted.
It always has these fields:

| Key              | Erlang Value                                           | JavaScript Value                                       |
| ---              | ------------                                           | ----------------                                       |
| gleam_error      | `assert`                                               | `"assert"`                                             |
| message          | The given message                                      | The given message                                      |
| kind             | The kind of asserted expression                        | The kind of asserted expression                        |
| start            | The byte-index of the start of the `assert` statement  | The byte-index of the start of the `assert` statement  |
| end              | The byte-index of the end of the `assert` expression   | The byte-index of the end of the `assert` expression   |
| expression_start | The byte-index of the start of the asserted expression | The byte-index of the start of the asserted expression |

But, depending on the expression that was asserted, it contains additional
information which can be used to diagnose the error.

### Binary operators

```gleam
assert level >= 30
```

| Key       | Erlang Type  | JavaScript Type  | Value                              |
| ---       | -----------  | ---------------  | -----                              |
| kind      | Atom         | String           | `binary_operator`                  |
| operator  | Atom         | String           | The binary operator that was used  |
| left      | Map          | Object           | The left hand side of the operator |
| right     | Map          | Object           | The left hand side of the operator |

### Function calls

```gleam
assert check_some_property(a, b, c)
```

| Key       | Erlang Type  | JavaScript Type  | Value                                  |
| ---       | -----------  | ---------------  | -----                                  |
| kind      | Atom         | String           | `function_call`                        |
| arguments | List of map  | Array of objects | The arguments of the asserted function |

### Other expressions

```gleam
assert other_expression
```

| Key        | Erlang Type  | JavaScript Type  | Value                                |
| ---        | -----------  | ---------------  | -----                                |
| kind       | Atom         | String           | `expression`                         |
| expression | Map          | Object           | The value of the asserted expression |

The expression maps have this structure:

| Key    | Erlang Type  | JavaScript Type  | Value                                                             |
| ---    | -----------  | ---------------  | -----                                                             |
| value  | any          | any              | the value the expression evaluated to at runtime                  |
| kind   | Atom         | String           | `literal` or `expression` or `unevaluated`                        |
| start  | Int          | Number           | The byte-index of the start of this expression in the source code |
| end    | Int          | Number           | The byte-index of the end of this expression in the source code   |

If the expression is a literal, such as `True` or `15`, it will have the `literal`
kind. This signals that its value is not runtime dependent, and may not need to
be printed.

If the expression is on the right hand side of a short-circuiting operator, like
`||` or `&&`, it might not be evaluated. If the operator short-circuits, the right
hand side expression will have kind `unevaluated`.

---

## File: test-community-packages/README.md

# test_community_packages

[](https://hex.pm/packages/test_community_packages)
[](https://test-community-packages.hexdocs.pm/)

```sh
gleam add test_community_packages
```
```gleam
import test_community_packages

pub fn main() {
  // TODO: An example of the project in use
}
```

Further documentation can be found at <https://test-community-packages.hexdocs.pm>.

## Development

```sh
gleam run   # Run the project
gleam test  # Run the tests
gleam shell # Run an Erlang shell
```