1. Debian though a functional lens
    1. Joey Hess, DebConf14

      Using Nix's functional package management as inspiration, let's look at Debian from a functional programming perspective.

    2. https://joeyh.name/talks/debconf-14-debian-through-a-functional-lens/
  2. a motivating example (haskell-dav)
    1. (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
      
    2. 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 
    3. 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 
    4. 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} 
    5. 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. 
    6. massive redundancy and make-work
      1. Debian Haskell Group maintains 844+ of these
      2. Debian perl Group: 3327+!
      3. ... that's 20% of the source packages in Debian
      4. ... and there are more
  3. 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;
      	  };
      	})
      
    1. ... not exactly ideal, but a lot better
  4. 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. 
  5. 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."
      			] 
  6. comparing debian/control types
    1. control :: ControlFile -- current
      1. ♥ simple
      2. X redundant boilerplate
      3. X inflexible
    2. control :: IO Control -- executable control file
      1. ♥ avoids boilerplate
      2. ♥ no language lock-in
      3. X cannot extract Control data w/o running arbitrary code
        1. seems to completely rule this out!
    3. gencontrol :: IO ControlFie -- pre-generate control file
      1. ♥ already available
        1. see "debdry - Debian Don't Repeat Yourself"
      2. ♥ avoids boilerplate
      3. ♥ no language lock-in
      4. X "this file was auto-generated. Please do NOT edit manually"
    4. control :: UpstreamSource -> Control -- control file as functional code
      1. ♥ avoids boilerplate
      2. ♥ purely functional safety
        1. control file generates same output given same inputs
        2. result not based on /etc/lsb_release or phase of the moon
      3. X language lock-in
        1. but language lock-in has not been a problem for debian/rules ...
  7. nixos exploration
    1. filesystem layout
      1. ldd $(which bash)
      2. which bash
      3. find /usr
      4. # explore /run/current-system and /nix briefly
    2. declarative package management
      1. man configuration.nix
      2. vim /etc/nixos/configuration.nix, make some changes
      3. nixos-rebuild switch
    3. generation based package management
      1. # as root or non-root (non-root updates ~/.nix)
      2. nix-env --install git-annex
      3. nix-env --list-generations
      4. nix-env --rollback
  8. functional runtime

      Increasingly, the running OS is like the runtime of a functional program.

    1. immutable data
      1. git commits
      2. docker images
      3. nix derivations
    2. copy on write
      1. git delta compression
      2. docker aufs layers
      3. nix generations
    3. garbage collection
      1. git gc
      2. docker images -f dangling=true # or something like that
      3. nix-env --delete-generations; nix-collect-garbage
  9. a progression: IO to declarative to FP
    1. debian/rules
      1. manual -- IO (cp foo bar)
      2. debhelper -- IO, some declarative (debian/install etc)
      3. dh -- declarative, some IO (override_dh_auto_*)
      4. ... FP?
        1. many debhelper feature requests are now about the
        2. limits of declarative configuration
          1. "debian/install is too inflexible"
    2. maintainer scripts
      1. manual -- IO
      2. debhelper autoscripts -- sorta declarative, still lots of IO
      3. triggers -- some declarative, some IO
      4. ... FP?
        1. talked with Russ yesterday about eliminating
        2. more maintainer scripts, he suggested an EDSL
        3. to simplify debconf config scripts
    3. config files
      1. just a static file -- declarative (mostly)
      2. debconf generated file -- IO (oops!)
      3. file.d -- FP-ish (Set File -> File)
    4. debian/copyright (a bit of a stretch)
      1. prose
        1. "This package was downloaded in 1997 from sunsite
        2. and it is GPL licensed by ESR."
      2. structured
        1. Copyright: 2009-2013 J. Random Hacker
        2. License: GPL-3+
      3. almost programming
        1. "License: $foo with $bar exception"
        2. "License: $X or $Y, and $Z"
    5. OS configuration
      1. apt-get install -- IO
      2. puppet/etc -- declarative-ish + IO
      3. docker -- declarative-ish (dockerfile)
      4. nixos -- FP