Wanted to share that my province, British Columbia, is pretty good about this. My team was hired to build BC’s Digital Marketplace (https://digital.gov.bc.ca/marketplace), which procures teams to build software for government that is licensed under the Apache 2 License!
Congrats to the core team! I'm super happy to see 0.19. We recently went live with a website that was fully written in Elm 0.18 (www.project6.com). I'm excited to upgrade to 0.19 and take advantage of the new browser package. If anyone is interested in learning more about the decision-making process behind choosing Elm for that project, I discussed it during an Elm Town podcast episode (https://elmtown.audio/the-risk-of-elm-dhruv-dang).
Great book to read if you are considering becoming a front-end developer! Instead of just "tolerating JavaScript's quirks", the author taught me how to use the language's unique features to build maintanable applications eloquently.
The main difference between the two is Nix's ideas come from functional programming, and Docker's are imperative. The practical outcome of this is that it's easier to keep your system clean over time with Nix than Docker because of the way it's been designed.
Nix isn't only a package manager, it is also a functional programming language intended for system administration. This means that, while a Nix file is comparative to a Dockerfile, it has several key differences:
1. All Nix files are just functions that take a number of arguments and return a system config (like a JSON object, but with some nice functionality). A Dockerfile is a set of commands you run to build a system to a "starting" state. This is imperative (you're telling the computer to "do this", then "do that", etc.), so once it's done, you can mutate state to deviate from what you specified in your Dockerfile. With Nix, while you can technically do this on some systems, it does provide you with the command line tools so you don't break things (e.g. nix-shell, nix-env). Note, on NixOS, other measures are taken to encourage safety.
2. If things go wrong in Nix(OS), the idea is that you can do a fresh install in your system, copy your old Nix file to it, and with one bash command, be back to where you were before things went haywire. In terms of containers, there's nothing new with this because this is exactly what Docker does. However, Nix also has this concept of generations, so every time you use a Nix command to change your system state either declaratively via a Nix file or imperatively in the command-line using nix-env, you can roll back to a previous version of state. This is especially nice with NixOS, because it creates generations for your entire system too (includes hardware config, drivers, kernel etc.), and makes separate GRUB entries for each generation, so if something breaks after you do a system upgrade, you just chose an old GRUB entry to go back to where you were. AFAIK, Docker doesn't offer anything like this, and this is a good example of how these tools' designs can impact their feature-set so dramatically.
3. A neat feature of Docker is composability. You can inherit from other, pre-existing Dockerfiles, and you can deploy multi-container apps with various tools. Composability at a single-container level is very straightforward with Nix. Since every config is just a function, you simply call the function exposed by a different Nix file with the correct arguments, and... voila! Once you've made your desired Nix file, you can run it either using nix-shell or nixos-container. While I'm no expert, I believe they perform better than Docker as they don't use virtualization. For multi-container deployment, there is NixOps. You write some Nix files describing the VMs you want to deploy, and run a bash command to deploy them to various back-ends (AWS, Azure, etc.). Again, the big difference here is that you can incrementally modify these VMs in a safe way using Nix. If you change your deployment config file, Nix will figure out something has changed, and modify the corresponding VMs to achieve the desired state.
Some may believe that Docker and Nix are very similar, and to their credit, they are in certain scenarios. The thing I like about Nix is that it's one language (and architecture) that was designed well. It's minimal, yet makes it possible to do so much in a safe way.
Nix has been around for a while, but I think the community is growing quickly as functional programming continues to take off. I'm excited to see where it goes, and am super grateful I have a tool like this to use while coding.
I can vouch for the immense improvement Nix has made to my software development process. I use NixOS on my desktop and laptop. At the OS-level, it gets a lot of things right: reproducible, immutable system configs; lightweight containers; devops with declarative configs. At a software project level, nix-shell is an indispensible tool. Compilers and interpreters aren't even part of my system-wide config; instead each project has it's own shell.nix file that installs all dependencies I need on the fly without polluting system state or virtualization. Nix is a god-send, and the developers that contribute to it are nothing short of awesome!
The area that needs improvement is the documentation. Once you learn the Nix language, reading the source code is pretty helpful, but it would be nice to make it more approachable. For example, the nixpkgs repo has a bunch of Nix helper functions that are useful to developers when writing their own packages, but these functions' documentation is either buried in a long manual, or non-existent.
The Zuk Z2 is good for devs. Costs around USD 260 from online Chinese retailers. Great specs and battery life, easily unlockable bootloader, and lots of unofficial cyanogenmod builds available if you search github.
Hey, sorry for the late reply. I have touched on React. But, I am familiar with Ember, Backbone, Vue and Riot. Nonetheless, could you please explain further?
Thanks for the essay, it was a great read. Maybe my understanding is wrong, but I am slightly perplexed by one idea. I really like the link you have created between the designer's and developer's workflow, and I think your essay touches on an ideal. But, from an applied perspective, this may be difficult to attain when creating components that need to visually transition between state within the original element.
Using your video player example, if the video is loading (state 1), and once loaded, it starts playing (state 2), wouldn't a pure functional approach imply the entire <video> DOM element is replaced by a new one in the change from state 1 to state 2? What if I only wanted to animate the loading bar away and fade out the thumbnail when leaving the loading state, while maintaining the original HTML element?
I'm curious to know if you've thought about this, and have any insight, because it's something I hope to understand. Thanks.