We've been experimenting at my day-job with using the nix package manager to
automate the fetching and building of dependencies, and also isolate them per
project/revision.
In the root of each project repository, we have a shell.nix file that lists all
dependencies needed to build and develop the project. Most of them are from the
latest major nixpkgs tarball and we include its hash to account for the hashes
of every package that it provides. Other packages are from e.g. PyPI, crates.io
or internal repositories and each of those have their own hashes.
With the shell.nix file we can then get a working environment set up by running
nix-shell or automatically when we enter the directory by using direnv. The
first time it will fetch and build everything but it will be cached after that.
This has worked quite well for us so far, it makes it very convenient to
maintain dependencies. We can try out new dependencies on a feature branch and
easily run CI on it, and when we merge the branch to master the dependencies
follow along automatically for both local and CI machines.
For older revisions or branches it is also very convenient to get a working
environment as you just need to check it out and load its shell.nix file. No
need to make sure your system has e.g. an older Python version available, it
will be fetched automatically. In theory, older revisions should be usable
indefinitively, as long as the sources we fetch the dependencies from are still
available.
To try to ensure that all required dependencies are included in the shell.nix
file our CI jobs run with nix-shell --pure to make sure it does not use any
system programs. However, this does not prevent e.g. using files or binaries
specified by an absolute path, if it is available both locally and from CI.
Preventing unneeded dependencies from being listed is also difficult, as that
requires removing a dependency and re-running everything to make sure nothing
breaks without it.
Thanks for pointing that out, str slice is surely better. I returned String in all versions just because collect() returns A String and I want to reuse the same test function. Will update this later.
It's a trade-off. I've once seen a memory leak in a JSON-handling code which was caused precisely by JSON parser returning a view into the underlying raw input: we stored one or two string fields from a large-ish (5 MiB IIRC) JSON and it prevented that whole JSON blob from being garbage collected.
This probably won't be an issue in Rust because there are very few situations where taking a reference can extend the lifetime of an object. It can really only happen for temporary objects where their lifetime can be extend to that of the function. It isn't nearly the same as a GCed language where it is very easy to accidentally keep an object alive for a long time.
It seems to be needed in the first "This is a sentence..." example as well. Right now it uses U for the lone "a" and I for the second syllable in "sentEnce". But U represents /ʌ/ (as in but) and I represents /ɪ/ (as in bit), but a symbol for /ə/ would be a better fit for these two, right?
The given symbols match the way the vowels represented are pronounced in at least some dialects/accents of English; one problem with trying to do a new phonetically-accurate writing system for English is that English has lots of dialects and accents, and pronunciation (even relatively—like which parts of words match which parts of other words) isn't consistent between them.
Thanks for pointing out these mistakes
- I added the schwa back into the vowel inventory (forgot to include in the original post)
- added clarification for how to write the “ir” in “bird” or “firm”
Currently, Germany is averaging around 6.4 GW of imports and 3.2 GW of exports. During production spikes caused by e.g. wind or solar power, the price quickly drops in the whole region, sometimes into the negative in order to help stabilize the grid frequency.
Besides for verifying that the compiled program works on the target, tests are also required to compile with PGO because you need to have a runtime example to optimize for.
> Then before I push, I have to temporarily rewind the branch to remove them, push, then cherry-pick them again.
You do not necessarily need to modify and restore your branch head just to push in this case. If you have e.g. two temporary commits at the top of the branch, you can use e.g. "git push origin HEAD~2:master" to skip those commits when pushing.
To me it feels like Cyrillic cursive has at least as many differences from its printed counterparts as Latin has. For example, д is written like a g, б kind of like a d, т like an m. The last one is especially confusing because м also exists.
It is not an entirely painfree experience, though. In some cases it is not a completely unwarranted question.
For example, the snow and ice melted here yesterday, exposing gravel on asphalt which is borderline painful to run on directly. Also, e.g. very cold winter days or just nasty gravel roads may inflict varying degrees of pain.
Otherwise, it can also be slightly painful for the soles during later parts of long runs, especially when inexperienced or when running for the first time in months.
What happened to C? It's the #5 top language and you never ruled it out but it is missing from the final list? It seems like a reasonable first language with simple operations and not much magic happening behind the scenes.
In the root of each project repository, we have a shell.nix file that lists all dependencies needed to build and develop the project. Most of them are from the latest major nixpkgs tarball and we include its hash to account for the hashes of every package that it provides. Other packages are from e.g. PyPI, crates.io or internal repositories and each of those have their own hashes.
With the shell.nix file we can then get a working environment set up by running nix-shell or automatically when we enter the directory by using direnv. The first time it will fetch and build everything but it will be cached after that.
This has worked quite well for us so far, it makes it very convenient to maintain dependencies. We can try out new dependencies on a feature branch and easily run CI on it, and when we merge the branch to master the dependencies follow along automatically for both local and CI machines.
For older revisions or branches it is also very convenient to get a working environment as you just need to check it out and load its shell.nix file. No need to make sure your system has e.g. an older Python version available, it will be fetched automatically. In theory, older revisions should be usable indefinitively, as long as the sources we fetch the dependencies from are still available.
To try to ensure that all required dependencies are included in the shell.nix file our CI jobs run with nix-shell --pure to make sure it does not use any system programs. However, this does not prevent e.g. using files or binaries specified by an absolute path, if it is available both locally and from CI. Preventing unneeded dependencies from being listed is also difficult, as that requires removing a dependency and re-running everything to make sure nothing breaks without it.