432 karma · joined October 5, 2021
No, systemd is a hard dependency for NixOS.
There are tools that make "bare metal" configuration reproducible (to varying degrees), e.g. NixOS, Ansible, building Amazon AMI images.
Tuples fall under product types. Rust's APIs return errors as sum types. A more apt comparison would be with Go, where errors are actually returned in tuples.
Edit: nevermind, I see what the author meant now!
1. https://hackage.haskell.org/package/tardis-0.4.4.0/docs/Cont...
2. https://rosettacode.org/wiki/Water_collected_between_towers?... (see the "see also" section for a Tardis implementation)
> Also worth checking out for more general use of LLMs in emacs: https://github.com/karthink/gptel
I suppose you could argue for anything with this reasoning.
Or, just use the magit-forge package by the same author and run `forge-fork`.
For language-specific formatting, you can run formatters in pre-commit-hooks and CI. Treefmt[2] can help with that if you want to cover a lot of languages in your repo.
Could you elaborate?
I definitely used to be a person who just didn't listen to music - I found it quite boring, really. I've since found genres that I like that I listen to on occasion, but definitely still not as frequently as the average person.
Though, Rust's type system and syntactical features probably lend themselves to more ergonomic handling of the various error states.
Consider the following pseudocode:
// Idris
binarySearch : SortedList a -> a -> Maybe Nat
binarySearch = ?implementation
// Java
int binarySearch(List<T> elems, T elem) {
assert isSorted(elems);
throw new NotImplemented();
}
(The generic type parameter should also implement Comparable or similar, but I digress).In this case, it would be nonsensical to pass an unsorted list to either procedure, so we prevent it - in Idris' case by using dependent typing; in Java's case by using assertions.
To contrast, consider the following:
// Idris
readLines : Path -> IO (Either FileError (List String))
readLines = ?implementation
Here, the FileError represents a number of things that could go wrong: no file existing at the given path, lack of permissions, running out of memory during read and so on. However, this is not misuse of the procedure - these are all expected deviations from the happy path, and hence we model that in the type definition.(I've omitted a corresponding Java example, as following a similar style would be terribly non-idiomatic. Java prefers throwing and catching exceptions to manage non-happy paths)
Note that we can't constrain the Path parameter to only resolve to files that exist. Doing so would require knowledge of the current filesystem state, e.g. the type signature would be something like the following:
readLines : (fs : FileSystem) -> (p : Path) -> fileExists fs p -> IO (Either FileError (List String))
readLines = ?implementation
To summarize, use preconditions, assertions or type-level constraints to prevent misuse of procedures. Return errors (using sum types, for example) when it is known and expected that the result of a procedure can deviate from the happy path. You may refrain from modeling conditions at the type level, even if possible in principle, as it may be prohibitively complex.