22 ms·
Nix-Powered Development with OCaml
- kirkfletcher 4y agoBeen a while since I used nix packages or nix-shell more specifically, my issue is that the packages are "tampered" with and not as distributed, making them prone to issues. I experienced quite a few problems previously
- 0x69420 4y agoout of curiosity, what sort of tampering/issues? in my experience such changes are largely to accommodate nix's admittedly alien expectations (runtime dependencies living in the store, etc etc) and beyond that things behave more vanilla than almost any linux distro's repos
- toastal 4y agoIn 2023, you shouldn’t be using nix-env or niv or shell.nix but rather just use Nix Flakes. It’s listed in the notes but this has long been where everyone has moved for a couple of years now (why it’s still “experimental” is a different question). If this is “Nix-powered”, why is everything done in the mutable shell instead of actually setting up the pure derivation so others can consume the build? Looking at opam-nix from Tweag might be a better route here. Also, why would anyone put a text editor in their devShell? Question to others: as someone with Nix experience and interested in learning OCaml but hasn’t quite bit the bullet, what does dune actually offer me if I’m using Nix to manage dependencies already? It feels like adding an unnecessary layer of LISP when Nix and opam should already cover everything.
- omniscient_oce 4y agoI'm not very familiar with Nix but Dune is a build system not a dependency manager. You would need it regardless.
- toastal 4y agoNix is a build system + dependency manager. So wouldn't that cover the use case? I know some packages use a Makefile with ocamlbuild or the like. I want less moving parts and less things to learn if I can.
- ghostwriter 4y agoHow would you provide incremental per-module compilation for your Nix derivation of the app?
- toastal 4y agoI don't know; that's why I'm asking. Maybe buildOpamPackage already does it? https://github.com/tweag/opam-nix#buildOpamProject https://github.com/tweag/opam-nix#buildOpamProject There's a buildDunePackage in the same region of the docs that runs `dune build` but that to me implies that dune is not needed(?). I haven't read too much into the project yet. The example (https://github.com/tweag/opam-nix/blob/4bb1a4c372f639f44fc6745f13c86f4397e82d34/examples/readme/my-package/my-package.opam https://github.com/tweag/opam-nix/blob/4bb1a4c372f639f44fc67...) would indicate that everything is configured from just the ${PROJECT}.opam file, but I don't have enough info on the toolchain to know if it's incremental per module or what... or if ocamlfind more complicated to work with than dune.
- ghostwriter 4y agoIt does run `dune build`, but the unit of persistence within Nix is defined as `buildDunePackage`, i.e. the Nix store will only know about the package rather than individual modules and a change in a single module will cause a cascading rebuild of the entire package to update the nix store.
- toastal 4y agoThere are tools out there for other languages that _can_ handle incremental & per-modules builds, such as purs-nix for PureScript, so if opam-nix doesn't now, I'm sure it will in the future as a lot of projects are asking for this feature.
- ghostwriter 4y agoWhy would I give up on shell.nix if flakes API isn't stable yet? I've got my own patterns around default.nix and shell.nix that provide better ergonomics than flakes.
- oever 4y agoFlakes have a lock file (flake.lock) which means you get to decide explicitly when to update the software. nixpkgs does not have precise rules on what updates are allowed, so nix-shell can give surprising results unless you make the effort to stick to one version of the whole nixpkgs explicitly. With flakes you can combine packages and versions explicitly.
- ghostwriter 4y ago> you make the effort to stick to one version of the whole nixpkgs explicitly. the "effort" is just pointing to a particular checkout from nixpkgs repo > With flakes you can combine packages and versions explicitly. it's the same thing with default.nix/shell.nix, just having a separate lockfile changes nothing in the underlying `builtins.fetchGit` / `builtins.fetchTarball`
- ParetoOptimal 4y agoFor your personal use, it sounds like it won't make sense. In a team setting, enforcing that everyone has to follow purity best practices because nothing else is allowed is great.
- chrissoundz 4y agoWhere does it say you shouldn't use nix-env, niv or shell.nix in 2023? I would argue that there is extensive documentation and functionality for that already and it's not like it's getting deprecated. I've used Nix/Nixos for the past 4 years and still haven't looked into flakes - all the Nix stuff I use works great so I just can't really be bothered to spend time learning more, though I don't doubt it has some advantages.
- toastal 4y agoMeanwhile, much of the Nix world is using the composable and standardized system of Flakes so they can easily share their derivations. Flakes are behind a flag, but are a part of `nix` and all of these other tools are adding dependencies and complexity to your system. The Nix Flake shells also start up much quicker. It's really worth a look because it can simplify your setup and make it easier for others to read your Nix code and not run into something unexpected or nonstandard.
- chriswarbo 4y agoI've been using Nix for about a decade, and not bothered with flakes yet. However, I also avoid nix-env and channels, as the parent suggests: - Instead of channels, I use fetchGit with pinned revisions - Instead of managing installed software via nix-env, I use buildEnv to collect everything I need in a single derivation. If I'm on NixOS I'll put that in systemPackages; or otherwise (e.g. on macOS) I'll use nix-env to only install that one package. These have the advantage of being declarative files, which can be tracked in git; rather than imperative commands.
- ParetoOptimal 4y ago> Where does it say you shouldn't use nix-env, niv or shell.nix in 2023? It's not in official documentation but the biggest reason is it's not reproducible by default and a new user could easily not pin nixpkgs, then think "wait... Nix isn't reproducible". nix-shell and niv or otherwise pinning nixpkgs is pretty good, though there are some reproducibility advantages flakes has over nix-shell + niv such as: - not allowing access to files not tracked in the git repo - forcing the user to lock their inputs with flake.lock whereas pinning/niv are optional Also see: https://nixos.wiki/wiki/Flakes#Making_your_evaluations_pure https://nixos.wiki/wiki/Flakes#Making_your_evaluations_pure
- AJRF 4y agoDo you know about nix-shell --pure?
- ParetoOptimal 4y agoIt's a good improvement, but still not as pure: https://nixos.wiki/wiki/Flakes#Making_your_evaluations_pure https://nixos.wiki/wiki/Flakes#Making_your_evaluations_pure
- johnvaluk 4y agoFor a feature that isn't enabled by default, "just use Nix Flakes" hardly qualifies as best practice or even commonplace. I've used Nix/NixOS for years and still don't have a use case for flakes. I only enabled it this week to restore some functionality to the nix command, which is still a work in progress. Getting there was painful and required a deep dive into the documentation. In the end, it was as simple as adding this line to my configuration.nix: nix.settings.experimental-features = [ "nix-command" "flakes" ]; The flexibility of Nix is one of its main selling points, so it's impossible to say that "everyone" uses it in a similar way. Flakes are a welcome, but disruptive, enhancement. Hopefully, the experimental phase will end soon.
- ingenieroariel 4y agoMost hardcore Nix users/developers I have met have been suspicious for Flakes for several years, so your point rings true. That said, it feels like they are slowly coming to terms with it and just accepting it as default. Here are two examples of maintainers eventually accepting flake support on their repos after initial hesitation [1][2]. [1] https://github.com/tpwrules/nixos-apple-silicon/pull/47 https://github.com/tpwrules/nixos-apple-silicon/pull/47 [2] https://github.com/NixOS/mobile-nixos/pull/404 https://github.com/NixOS/mobile-nixos/pull/404
- toastal 4y agoCounter anecdote: all of the hardcore Nix users/developers convinced me it was worth it to switch to Flakes now. They even helped me move my NixOS config as well.
- baby 4y agoIt sounds like a python 2 vs python 3 kind of deal, which intuitively makes me think that you should just use flakes
- mikepurvis 4y agoI'm a relative newcomer too— started about two years ago with a Flake-only workflow on Nix 2.3. My sense in observing the debate over this time is that about 20% of the objections are technical in nature, while 80% are around governance— feeling that the feature was smuggled into the main repo as a prototype, despite there being existing external projects (niv) that were trying to accomplish a lot of the same things.
- baby 4y agoDune doesn’t handle dependencies for you, you just use it to build your ocaml projects with a list of dependencies (often without specifying dependency versions, which is why dune doesn’t really work without nix)
- momentoftop 4y agoNix can replace opam, which is the dependency manager supporting isolated ocaml environments. I generally try to use Ocaml now without opam, and just using Nix. You'll still want dune, though I could see an argument for generating the dune files from nix expressions.
- toastal 4y agoIsn't opam read upstream for the public package registry? It seems like opam is the one you need.
- rkangel 4y ago> In 2023, you shouldn’t be using nix-env or niv or shell.nix but rather just use Nix Flakes I've found quite a few articles on alternatives to nix-shell in the flakes world, but I haven't found one for this usecase (which is also my main Nix usecase). Particularly, how do I have a flakes equivalent for nix-shell that isn't pure? It is convenient to be able to run git, or SSH or whatever from my development shell, and those things shouldn't be in my project build setup.
- ocimbote 4y agoAfter a lot of hesitation and energized by a work incentive, I tried Nix last week. I've followed the official docs, had to resort on Google et al. quite quickly to solve mundane problems (installing a channel is not on the default path of the docs for the new learner), and after much wandering and trial and error, I evenrially went to the discourse and asked what I should use between flakes, nix shell or develop... Every single answer was 1/extremely informative and nice 2/ crystal clear that Nix was in a confusing, in-between stage in its life cycle. I very much appreciate the community and efforts but I work for a company that cannot afford the commitment that Nix requires right now. I will happily come back in 2 years and reevaluate.
- Buttons840 4y agoWhat exactly are they in-between? What is changing and how will things be better in 2 years?
- rgoulter 4y agoThe Nix Flakes feature. Previously, Nix installed its packages using 'channels'. You would add and update a channel, and then you could install packages from a channel. (This is roughly analogous to apt repositories). -- The CLI user experience for this channel-based approach is pretty terrible. Nix flakes are a new feature where a project has a `flake.nix` file, which follows a standard format for declaring what packages a project provides. -- The CLI experience is much nicer, and has several other benefits over pre-flake Nix. Flakes are still (for various reasons) labelled as "experimental". Much of the documentation has not been updated for flakes. In 2 years, you'd hope that: the documentation improves, and there's less friction for adopting the technology.
- ocimbote 4y agoMy most personal example of the CLI being in-between state and the community agreeing to it is in this thread: https://discourse.nixos.org/t/nix-shell-nix-shell-and-nix-develop/25964 https://discourse.nixos.org/t/nix-shell-nix-shell-and-nix-de...
- shepardrtc 4y ago
- weitzj 4y agoI really would like to use it in the enterprise. But secure boot was not easy to do the last time I used it. And i still don’t have a clue how to package things which are delivered as Deb or rpm packages (I.e. a vpn client) And getting management approval to build a packaging team so that you are not the only person In the company to go to, is a hard sell
- kaba0 4y agoWell if there is no other source/binary available then you have to uncompress the deb/rpm file (both have some utility for that), look up the dependencies from somewhere, copy the extracted files over to the nix output dir, and patch-elf all the binaries to link to the nix-version of the dynamic lib. This sounds more difficult than it is, the result will be a copied over binary file that has its “libc.so” and other dynamic libs replaced in the ELF-header with “/nix/store/hdjdewuieu737-libc/libc.so”. I recommend looking up a package in nixpkgs which has a similar install story, that’s the easiest way to write a new package. In case you only want to run it locally https://github.com/thiagokokada/nix-alien https://github.com/thiagokokada/nix-alien and similar programs work fine with the binary.
- phaer 4y agoAfaik it's not finished yet, but there recently has been quite a lot of activity regarding secureboot for nixos https://github.com/nix-community/lanzaboote/ https://github.com/nix-community/lanzaboote/
- ingenieroariel 4y agoIf you are mainly using OCaml and do not mind flakes, this was a very good starting point for me: https://github.com/brendanzab/ocaml-flake-example/blob/main/flake.nix https://github.com/brendanzab/ocaml-flake-example/blob/main/... Using Flakes you can have a devShell, a check target and a build target neatly organized.
- l_theanine 4y agoOcaml seems somewhat hampered by this weird disconnect between upstream maintainers and Jane Street and other third party major users. Popular media for ocaml learners describes using Base, while documentation focuses on the builtins, which clearly aren’t used that often in practice. Do I have this wrong? Why doesn’t Ocaml just merge Base (with permission) and put their best foot forward for the ecosystem?
- frou_dh 4y agoYou have it wrong. The official standard library is under constant development and in practice many people use it and not the Jane Street stuff.
- anentropic 4y agoI don't think they're wrong the Jane Street side are quite prolific with blog posts etc as a newcomer to OCaml one of the first, and nicer-looking, intro resources you'll likely encounter is the Real World OCaml book https://dev.realworldocaml.org/ https://dev.realworldocaml.org/ which unfortunately does everything using Base instead of the stdlib Personally that didn't sit right to me and I prefer to use the stdlib by default (which seems fine and not in need of a wholesale replacement)
- frou_dh 4y agoThere definitely is indeed a problem, namely a false perception that the stdlib is a moribund relic with one foot in the grave. What I'm saying is that it's fairly healthy and gets used plenty by general OCaml users.
- l_theanine 4y agoAre there some large users or projects that are committed to the stdlib and not Base that I could look into or read about? Thanks in advance.
- anentropic 4y ago
- domenkozar 4y agoIf you decide to try https://devenv.sh https://devenv.sh, it has OCaml support built-in: $ cat devenv.nix { config, ...}: let ocamlPackages = config.languages.ocaml.packages; in { languages.ocaml.enable = true; packages = [ ocamlPackages.janeStreet.async ]; } $ devenv shell ... Recently also shipped 0.6 with container generation support: https://devenv.sh/containers/ https://devenv.sh/containers/ Let me know if you give it a try :)
- giraj 4y agoI was hoping this post would mention using OCaml with flambda[1] enabled. At least for my work, flambda seems to yield a ~10% speed up when compiling things. Can you get OCaml binaries with flambda enabled through Nix? With opam, I currently have to compile OCaml myself to enable it, as I am not aware of any binaries being distributed. [1] https://v2.ocaml.org/manual/flambda.html https://v2.ocaml.org/manual/flambda.html
- ingenieroariel 4y agoSeems you would need to first override ocaml and then override the ocaml used in mkOcamlPackages. [1] let o = ocaml.override { flambdaSupport = true; }; in let oP = ocaml-ng.mkOcamlPackages o (self: super: {}); in oP.apron [1] https://discourse.nixos.org/t/install-ocaml-flambda-compiler/1618 https://discourse.nixos.org/t/install-ocaml-flambda-compiler...
- giraj 4y agoOkay, thanks! But doesn't this still mean you have to compile ocaml (with flambda) yourself?
- mindslight 4y agoIf the derivation has already been written (as GP implies), then compiling something yourself with Nix is essentially just a longer installation process. No downloading tarballs, no keeping track of things in /usr/local, no stow or manually adding things to your path. Nix is essentially a source distribution that pulls common binaries from caches.
- baby 4y agoI actively work on an OCaml project and couldn’t understand anything about what flambda does from its readme
- giraj 4y agoI updated the link to point to the docs, which are more informative. As far as I understand, flambda is an intermediate representation of OCaml which allows for a number of optimisations and better inlining. You can check if you already have flambda enabled by runnning "ocamlopt -config | grep flambda". If you're using opam then you can test flambda out by creating a new switch opam switch create ocaml-flambda ocaml-variants.4.14.1+options ocaml-option-flambda and then running "opam switch set ocaml-flambda". (You can replace 4.14.1 with your preferred version above.)
- baby 4y agoWhy not use the new nix develop, etc. commands?
- return_to_monke 4y agoBecause nix develop is inherently a flakes-bound feature, and Nix Flakes aren't officially stable yet.
- rkangel 4y agoUntil the Nix team is happy to even enable flakes by default in releases, I don't think it is reasonable to expect people to use them by default.
- schemescape 4y agoDoes anyone know why Nix takes up roughly 500 MB with no packages installed? I want to try NixOS, but the “minimal” image is over twice as big as my full (terminal only) development environment using Alpine Linux. I was kind of expecting NixOS to be closer in size to a glibc-based minimal distribution (after initial install)…
- deleted 4y ago[deleted]
- pveierland 4y agoFor those new to Nix and flakes, I created a small OCaml development shell demo based on the blog post. MyNixOS lets you create flakes using a graphical editor and generates a reproducible flake with corresponding Nix code and lockfile. https://mynixos.com/pveierland/demo-ocaml/outputs https://mynixos.com/pveierland/demo-ocaml/outputs Run using: nix develop https://api.mynixos.com/pveierland/demo-ocaml/archive/latest.tar.gz
- deleted 4y ago[deleted]
- rkangel 4y agoThere is an extra superpower here that isn't mentioned - you can then trivially turn this into a CI job. This is a valid complete .gitlab-ci.yml file for the setup in this blog post: image: nixos/nix:latest before_script: - nix-env -f shell.nix -i -A buildInputs full_build: stage: build script: - dune build This uses a standard docker container with Nix built in. The before_script magic then installs everything into that container exactly as it is in your development environment. Subsequent commands then run exactly as in your environment. Of course with this approach, every CI job builds your whole environment. If this complex, and involves many compilation steps, then that is painful and you will instead want to use the nix setup to build a docker image that is used for your CI. For many projects involving small teams, that isn't necessary though and this works really well.