Debian though a functional lens Joey Hess, DebConf14 : Using Nix's functional package management as inspiration, : let's look at Debian from a functional programming perspective. https://joeyh.name/talks/debconf-14-debian-through-a-functional-lens/ a motivating example (haskell-dav) (picked because Clint is in the audience) ; % wc -l debian/rules debian/control Network/Protocol/HTTP/DAV.hs DAV.cabal ; 8 debian/rules ; 126 debian/control ; 444 Network/Protocol/HTTP/DAV.hs ; 79 DAV.cabal Build-Depends: debhelper (>= 9) ; , haskell-devscripts (>= 0.8.13) ; , cdbs ; , ghc ; , ghc-prof ; , ghc-ghci ; , libghc-case-insensitive-dev (>= 0.4) ; , libghc-case-insensitive-prof ; , libghc-either-dev (>= 4.1) ; , libghc-either-prof ; , libghc-errors-dev ; , libghc-errors-prof ; , libghc-http-client-dev (>= 0.2) ; , libghc-http-client-prof ; , libghc-http-client-tls-dev (>= 0.2) ; , libghc-http-client-tls-prof ; , libghc-http-types-dev (>= 0.7) ; , libghc-http-types-prof ; , libghc-lens-dev (>= 3.0) ; , libghc-lens-prof ; , libghc-lifted-base-dev (>= 0.1) ; , libghc-lifted-base-prof ; , libghc-monad-control-dev (>= 0.3.2) ; , libghc-monad-control-prof ; , libghc-mtl-dev (>= 2.1) ; , libghc-mtl-prof ; , libghc-network-dev (>= 2.3) ; , libghc-network-prof ; , libghc-optparse-applicative-dev (>= 0.5.0) ; , libghc-optparse-applicative-prof ; , libghc-transformers-dev (>= 0.3) ; , libghc-transformers-prof ; , libghc-transformers-base-dev ; , libghc-transformers-base-prof ; , libghc-utf8-string-dev ; , libghc-utf8-string-prof ; , libghc-xml-conduit-dev (>= 1.0) ; , libghc-xml-conduit-dev (<< 1.3) ; , libghc-xml-conduit-prof ; , libghc-xml-hamlet-dev (>= 0.4) ; , libghc-xml-hamlet-dev (<< 0.5) ; , libghc-xml-hamlet-prof Build-Depends-Indep: ghc-doc ; , libghc-case-insensitive-doc ; , libghc-either-doc ; , libghc-errors-doc ; , libghc-http-client-doc ; , libghc-http-client-tls-doc ; , libghc-http-types-doc ; , libghc-lens-doc ; , libghc-lifted-base-doc ; , libghc-monad-control-doc ; , libghc-mtl-doc ; , libghc-network-doc ; , libghc-optparse-applicative-doc ; , libghc-transformers-doc ; , libghc-transformers-base-doc ; , libghc-utf8-string-doc ; , libghc-xml-conduit-doc ; , libghc-xml-hamlet-doc boilerplate (repeated 3 times in this package) ; Package: libghc-dav-{dev,prof,doc} ; Architecture: any ; Depends: ${shlibs:Depends} ; , ${haskell:Depends} ; , ${misc:Depends} ; Recommends: ${haskell:Recommends} ; Suggests: ${haskell:Suggests} ; Provides: ${haskell:Provides} ; Description: ${haskell:ShortDescription}${haskell:ShortBlurb} ; ${haskell:LongDescription} ; . ; ${haskell:Blurb} rudimentary control file refactoring ; X-Description: RFC 4918 WebDAV support ; This is a library for the Web Distributed Authoring and ; Versioning (WebDAV) extensions to HTTP. At present it ; supports a very small subset of client functionality. massive redundancy and make-work Debian Haskell Group maintains 844+ of these Debian perl Group: 3327+! ... that's 20% of the source packages in Debian ... and there are more nixos equivalent ; # This file was auto-generated by cabal2nix. Please do NOT edit manually! ; { cabal, caseInsensitive, either, errors, httpClient, httpClientTls ; , httpTypes, lens, liftedBase, monadControl, mtl, network ; , optparseApplicative, transformers, transformersBase, xmlConduit ; , xmlHamlet ; }: ; cabal.mkDerivation (self: { ; pname = "DAV"; ; version = "0.8"; ; sha256 = "0khjid5jaaf4c3xn9cbph8ay4ibqr7pg3b3w7d0kfvci90ksc08r"; ; isLibrary = true; ; isExecutable = true; ; buildDepends = [ ; caseInsensitive either errors httpClient httpClientTls httpTypes ; lens liftedBase monadControl mtl network optparseApplicative ; transformers transformersBase xmlConduit xmlHamlet ; ]; ; jailbreak = true; ; meta = { ; homepage = "http://floss.scru.org/hDAV"; ; description = "RFC 4918 WebDAV support"; ; license = self.stdenv.lib.licenses.gpl3; ; platforms = self.ghc.meta.platforms; ; }; ; }) ... not exactly ideal, but a lot better debian/control dream equivalent (take 1) ; { haskell_libraries } ; Section: web ; Standards-Version: 3.9.5 ; ; Package: hdav ; Depends: { haskell_depends } ; Description: command-line WebDAV client ; hdav currently only supports copying a file and associated WebDAV ; properties from one URL to another. debian/control dream equivalent (take 2) ; -- valid haskell code this time ; source = haskell_source ; & section Web ; & standardsversion 3.9.5 ; packages = haskell_libraries `also` package "hdav" ; & depends haskell_depends ; & description "command-line WebDAV client" ; [ "hdav currently only supports copying a file and associated WebDAV" ; , "properties from one URL to another." ; ] comparing debian/control types control :: ControlFile -- current ♥ simple X redundant boilerplate X inflexible control :: IO Control -- executable control file ♥ avoids boilerplate ♥ no language lock-in X cannot extract Control data w/o running arbitrary code seems to completely rule this out! gencontrol :: IO ControlFie -- pre-generate control file ♥ already available see "debdry - Debian Don't Repeat Yourself" ♥ avoids boilerplate ♥ no language lock-in X "this file was auto-generated. Please do NOT edit manually" control :: UpstreamSource -> Control -- control file as functional code ♥ avoids boilerplate ♥ purely functional safety control file generates same output given same inputs result not based on /etc/lsb_release or phase of the moon X language lock-in but language lock-in has not been a problem for debian/rules ... nixos exploration filesystem layout ldd $(which bash) which bash find /usr # explore /run/current-system and /nix briefly declarative package management man configuration.nix vim /etc/nixos/configuration.nix, make some changes nixos-rebuild switch generation based package management # as root or non-root (non-root updates ~/.nix) nix-env --install git-annex nix-env --list-generations nix-env --rollback functional runtime : Increasingly, the running OS is like the runtime : of a functional program. immutable data git commits docker images nix derivations copy on write git delta compression docker aufs layers nix generations garbage collection git gc docker images -f dangling=true # or something like that nix-env --delete-generations; nix-collect-garbage a progression: IO to declarative to FP debian/rules manual -- IO (cp foo bar) debhelper -- IO, some declarative (debian/install etc) dh -- declarative, some IO (override_dh_auto_*) ... FP? many debhelper feature requests are now about the limits of declarative configuration "debian/install is too inflexible" maintainer scripts manual -- IO debhelper autoscripts -- sorta declarative, still lots of IO triggers -- some declarative, some IO ... FP? talked with Russ yesterday about eliminating more maintainer scripts, he suggested an EDSL to simplify debconf config scripts config files just a static file -- declarative (mostly) debconf generated file -- IO (oops!) file.d -- FP-ish (Set File -> File) debian/copyright (a bit of a stretch) prose "This package was downloaded in 1997 from sunsite and it is GPL licensed by ESR." structured Copyright: 2009-2013 J. Random Hacker License: GPL-3+ almost programming "License: $foo with $bar exception" "License: $X or $Y, and $Z" OS configuration apt-get install -- IO puppet/etc -- declarative-ish + IO docker -- declarative-ish (dockerfile) nixos -- FP