Skip to content

Commit

Permalink
create about chapter
Browse files Browse the repository at this point in the history
  • Loading branch information
PgBiel committed Apr 19, 2024
1 parent 15ed35d commit cef0516
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 8 deletions.
11 changes: 6 additions & 5 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

[Introduction](README.md)

- [About Glistix](./about/README.md)
- [Goals & Roadmap](./about/goals-roadmap.md)
- [Known Issues](./about/known-issues.md)
- [Contributing]()
- [Thanks](./about/thanks.md)

# Usage

- [Getting Started](./getting-started/README.md)
Expand Down Expand Up @@ -32,8 +38,3 @@
- [General modifications](./contributors/architecture/general-modifications.md)
- [Nix Backend]()
- [CLI modifications]()

# Misc

- [Goals]()
- [Thanks](./thanks.md)
5 changes: 5 additions & 0 deletions src/about/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# About Glistix

This chapter presents important general information regarding Glistix.

Check out the [Getting Started](../getting-started/README.md) chapter once you're ready to start using Glistix!
32 changes: 32 additions & 0 deletions src/about/goals-roadmap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Goals & Roadmap

## Glistix's Goals

Glistix has the following **primary goals**:

1. **Provide and maintain a Nix compilation target for Gleam.** That is, you should be able to write Gleam code and use it with Nix, aiming to **improve the Nix development experience** thanks to Gleam's **compile-time guarantees, type-safety and great tooling**, which should also **improve the accessibility and lower the entry barrier of working with Nix** (especially when it is needed to create complex and dynamic Nix configurations).

2. **Integrate the Gleam ecosystem with the Nix ecosystem as much as possible.** In particular, the existing [packages for Gleam](https://packages.gleam.run) should be made usable within Nix where possible.

In addition, we have the following **secondary goals**:

1. **Aid proper usage of the Gleam programming language among Nix users.** The tools we are creating to use Glistix within Nix, such as builders for packages, should ideally be easily reusable for the upstream Gleam compiler as well, eventually including proper support for the Erlang and JavaScript targets, if possible.

2. **Provide packages and bindings to aid in interacting with the Nix ecosystem from projects using Glistix.** For example, we'd like to release bindings for the easy creation of NixOS modules, configuration of flakes etc. with pure Gleam, and maybe even integrate some of those into the compiler itself. Our first step so far has been the creation of [the `glistix_nix` package](https://github.com/glistix/nix).

3. **Contribute back to the upstream Gleam compiler where possible.** We have certain needs and challenges which are shared with Gleam users which use the Erlang and JavaScript targets. Therefore, **where possible, we'd like to contribute our solutions to upstream** and use them, in order to ensure we maintain some amount of uniformity with the rest of the Gleam ecosystem. This doesn't mean we can't add features exclusive to Glistix, but, **if they aren't Nix-related, they should be kept to a minimum**.

Finally, we want to clarify what **we are NOT trying to achieve:**

1. **Glistix is not meant to replace or compete with Gleam.** Rather, we are focused on **extending and integrating Gleam to the Nix ecosystem.** This includes the addition of the Nix target, but also the maintenance of tools to improve the Gleam on Nix experience as much as possible, as outlined above.

2. **Glistix is not meant to replace all usage of the Nix language.** We do want to provide a **better experience** when working with Nix, but it is absolutely not our goal (nor is it practical) to have Nix users switch to using exclusively Glistix for their configurations and other applications of Nix. This is also because **Nix's** (and `nixpkgs`) **APIs are large and change relatively often**, and thus it is not possible to always provide fully accurate type bindings for all aspects of the Nix ecosystem.

## Roadmap

Here is a non-exhaustive list of tasks we want to eventually tackle within the Glistix project. This can change at any time.

- [ ] **Add more real-world examples** and generally **make the documentation more robust.**
- [ ] Add some form of **tail-call optimization.** This depends on changes to Nix itself to be fully practical, but there might be improvements we can make in the meantime.
- [ ] Fully decide the semantics of **Nix's lazy evaluation** when using Glistix. In particular, we should take a final stance on how discarded expressions behave in this regard by default.
- [ ] **Improve the package management and patching story.** We should cooperate with the upstream Gleam compiler to avoid future incompatibilities. Currently, our methods of overriding the Gleam standard library through Git submodules are quite manual and need replacement with proper Git dependencies together with requirement overriding.
76 changes: 76 additions & 0 deletions src/about/known-issues.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Known Issues

Here is a non-exhaustive list of relevant issues and warnings to consider when using Glistix.

## Missing tail-call optimization

Compared to Gleam's Erlang and JavaScript targets, Glistix's Nix target **does not have tail-call optimization.** This means that **recursion continually grows the stack** and, as such, **it is possible to trigger stack overflows** on Nix through deep enough recursion. As a consequence, at least for now, **you should avoid relying on recursion to process very large data.**

There are some ways to try to work around this limitation:

1. Gleam's built-in `List` type works as a linked list across all targets (including Nix). It is therefore **ideal for recursion**, but **should be avoided when recursion needs to be avoided** (e.g. because the list might have thousands of elements). In those cases, **consider using Nix's arrays** (called "lists" in Nix's official docs) instead. The [`glistix_nix` package](https://github.com/glistix/nix) contains **various helpful functions** to aid you in using arrays. The array functions avoid recursion where possible (functions using recursion indicate they are doing so clearly in the docs - they are few).

2. It is possible to use Nix's `builtins.genericClosure` function to improve efficiency when traversing lots of data, as it **allows creating arrays from existing (possibly recursive) structures**, but **is not recursive** itself, thus allowing for some light "tail-call optimization" in some cases, particularly when you need to create arrays.
- For more information, check out this great NixOS Discourse thread by user _sternenseemann_: [https://discourse.nixos.org/t/tail-call-optimization-in-nix-today/17763](https://discourse.nixos.org/t/tail-call-optimization-in-nix-today/17763)

## Lazy evaluation

Nix code is **evaluated lazily**, meaning **an expression isn't evaluated until requested.** This has implications on side-effects, such as when using logging for debugging during development; more importantly, however, **values which aren't evaluated lead to the creation of thunks** in memory; Creating too many thunks **can lead to slowdown and/or high RAM usage.** Therefore, and especially when working with complex and/or heavy programs or code within Nix, **try to reduce recursion and memory usage as much as possible** to avoid surprises.

### Discarded expressions

Due to the above, it is natural that **expressions not bound to any variables would never be evaluated** (in principle), due to laziness. To tackle that, **Glistix ensures all discarded expressions are evaluated** (at least shallowly). For example:

```rs
pub fn main() {
// The panic below won't run due to laziness.
// The variable is never used.
let var = panic as "message"

// The panic below, however, WILL run.
// Glistix forces discarded expressions
// to be evaluated before the function's
// return value using Nix's `builtins.seq`
// functionality.
panic as "other message"

// The panic below will also run.
let _ = panic

// However, the panic below won't run,
// as the evaluation of discarded expressions
// is shallow.
// This might change in the future.
#(panic as "inside tuple")

// It is worth saying that any returned values
// are evaluated, of course.
Nil
}
```

To force deep evaluation of expressions, you can use the `nix.deep_eval` function from [the `glistix_nix` package](https://github.com/glistix/nix):

```rs
import glistix/nix

pub fn main() {
nix.deep_eval(#(panic as "this will run"))

Nil
}
```

Additionally, **assertions are always evaluated:**

```rs
pub fn main() {
// This will cause a panic, even though
// this expression doesn't bind any variables.
let assert False = True

Ok("finished")
}
```

Glistix does this as certain packages rely on this behavior, such as as `gleeunit` (the default test runner), which generally **encourages performing multiple assertions in one function**, for example - however, said assertions are usually done through **function calls not bound to any variables** (or `let assert` expressions). In other words, if discarded expressions were ignored, **the test suites of multiple packages would simply not do (almost) anything,** as multiple assertions per test function are often used and their side effects (of panicking upon failure) relied upon.
7 changes: 7 additions & 0 deletions src/about/thanks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Thanks

- Thanks to [Louis Pilfold](https://github.com/lpil) and the rest of [the Gleam team](https://github.com/gleam-lang) for their amazing work on the Gleam compiler and the Gleam ecosystem, which was fundamental for Glistix to come to exist.

- Thanks to the [Purenix project](https://github.com/purenix-org/purenix) for being one of our main inspirations. It has a lot of goals in common with the Glistix project, and generally demonstrated that the initial idea which led to Glistix could actually have been something viable to do.

- More generally, thanks to all contributors to Nix and the aforementioned projects as well.
3 changes: 0 additions & 3 deletions src/thanks.md

This file was deleted.

0 comments on commit cef0516

Please sign in to comment.