Revamp:
- Switch from `cabal2nix` and haskell overlay to `developPackage` - Restructure directories to have more descriptive names - Fix `nix run`
This commit is contained in:
57
www/posts/2022-10-16-tangling-org-files.md
Normal file
57
www/posts/2022-10-16-tangling-org-files.md
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
title: "Tangling Org files with Nix"
|
||||
keywords: nix, emacs, org-mode
|
||||
image: './images/nix_banner.png'
|
||||
series: "Nix shorts"
|
||||
---
|
||||
|
||||
# Tangling Org files with Nix
|
||||
|
||||
One of the great wonders about Emacs [Org Mode][org] is its builtin functionality for [literate programming][lit-prog]. This allows us to write code inbetween text as if it was a research article, or a markdown file, but still export and run the code. By using emacs, we can keep our source files as articles, and only extract the source code when we export the code to the nix store.
|
||||
|
||||
## Example
|
||||
|
||||
```org
|
||||
# hello_world.org
|
||||
|
||||
#+TITLE: How to write hello world in javascript
|
||||
#+AUTHOR: h7x4
|
||||
#+PROPERTY: header-args :js :tangle yes
|
||||
|
||||
Here's how:
|
||||
|
||||
#+BEGIN_SRC js
|
||||
console.log("Hello World");
|
||||
#+END_SRC
|
||||
|
||||
Woah!
|
||||
```
|
||||
|
||||
```nix
|
||||
# default.nix
|
||||
{ pkgs, stdenvNoCC }:
|
||||
stdenvNoCC.mkDerivation {
|
||||
name = "hello-world-js";
|
||||
src = ./.;
|
||||
|
||||
buildInputs = with pkgs; [ emacs ];
|
||||
buildPhase = ''
|
||||
emacs --batch -l org hello_world.org -f org-babel-tangle
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
cp hello_world.js $out
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
## Tangling Nix Code?
|
||||
|
||||
Unfortunately, this isn't as declarative as the previous part. If we were to process literate nix using a nix file, it would end up in the nix store. That would require us to use [import from derivation][ifd], which brings all sorts of whackiness.
|
||||
|
||||
Instead, you should probably use emacs interactively to tangle the nix files, or just keep the nix files raw altogether.
|
||||
|
||||
[org]: https://orgmode.org/
|
||||
[lit-prog]: https://en.wikipedia.org/wiki/Literate_programming
|
||||
[ifd]: https://nixos.wiki/wiki/Import_From_Derivation
|
||||
|
||||
58
www/posts/2022-10-16-the-arrow-operator.md
Normal file
58
www/posts/2022-10-16-the-arrow-operator.md
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
title: "The nix arrow operator"
|
||||
keywords: nix, short, language, programming-language
|
||||
image: './images/nix_banner.png'
|
||||
series: "Nix shorts"
|
||||
---
|
||||
|
||||
There is a specal operator in nix, written as `->`. It is not a [C dereference struct pointer operator][c-deref-struct], nor is it a [haskell function type definition][haskell-function]. It is a boolean operator, which represents the "implies arrow" from [propositional logic][prop-log]. This is especially useful in nix, because of its usage in modules.
|
||||
|
||||
## The `myService` module
|
||||
|
||||
Let's say you have made a module for `myService` with two options called `myService.enable`, and `myService.address`. `myService` needs an address in order to work properly. If `myService` is not enabled, the value of `myService.address` doesn't really matter. Set or `null`, the result will be the same either way. If `myService` is enabled however, it is crucial that we report an error if `myService.address` is not set. `myService` can not work without it.
|
||||
|
||||
In order to make sure that this never happens, we need to assert that this is not the case. This could be done by asserting that this boolean expression is true.
|
||||
|
||||
`((!myService.enable) || myService.address != null)`
|
||||
|
||||
or in plain english: "Either myService is not enabled, or the address has to not be null"
|
||||
|
||||
This is equivalent to this boolean expression:
|
||||
|
||||
`myService.enable -> myService.address != null`
|
||||
|
||||
or in plain english: "myService being enabled implies that the address is not null".
|
||||
|
||||
Asserting these kinds of inter-setting dependencies are common enough in nix modules to provide grounds for having `->` as its own boolean operator.
|
||||
|
||||
## Full example
|
||||
|
||||
```nix
|
||||
# modules/myService.nix
|
||||
{ lib, config }: let
|
||||
cfg = config.myService;
|
||||
in {
|
||||
options = {
|
||||
enable = lib.mkEnableOption "myService";
|
||||
address = lib.mkOption {
|
||||
example = "127.0.0.1";
|
||||
description = "The address of myService";
|
||||
type = lib.types.string;
|
||||
};
|
||||
};
|
||||
config = {
|
||||
# ...
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.enable -> cfg.address != null;
|
||||
message = "myService needs an address";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
[c-deref-struct]: https://www.digitalocean.com/community/tutorials/arrow-operator-c-plus-plus
|
||||
[haskell-function]: http://learnyouahaskell.com/functors-applicative-functors-and-monoids
|
||||
[prop-log]: https://iep.utm.edu/prop-log/
|
||||
Reference in New Issue
Block a user