aboutsummaryrefslogtreecommitdiff
path: root/index.html
blob: 4b660a4c8509557618896a9bb4f076babb02b919 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <title>Is GNU Guix a minimal distribution?</title>

    <link rel="stylesheet" href="dist/reset.css">
    <link rel="stylesheet" href="dist/reveal.css">
    <link rel="stylesheet" href="dist/theme/white.css" id="theme">

    <!-- Theme used for syntax highlighted code -->
    <link rel="stylesheet" href="plugin/highlight/monokai.css" id="highlight-theme">

    <link rel="stylesheet" type="text/css" href="css/asciinema-player.css" />

    <style>
     body .reveal {
         font-size: 56px;
     }
     .reveal p {
         margin-bottom: 38px;
     }
     .reveal h1 {
         text-transform: unset;
         margin-bottom: 38px;
         font-weight: normal;
     }
     .reveal h2 {
         text-transform: unset;
         margin-bottom: 38px;
     }
     .reveal h3 {
         text-transform: unset;
         margin-bottom: 38px;
     }
     .reveal h4 {
         text-transform: unset;
         margin-bottom: 38px;
     }
     .reveal .slides .dark-section {
         color: #FFF;

     }
     .reveal .slides .dark-section h3 {
         color: #FFF;
     }
     .reveal .slides .dark-section h4 {
         color: #FFF;
     }
     .revealed-fragment {
         opacity: 0.5;
     }
    </style>
  </head>
  <body>
    <div class="reveal">
      <div class="slides">
        <section>
          <h3>Is GNU Guix a minimal distribution,<br>and what might that even mean?</h3>
          <p style="font-size: 0.7em;">Presented by Christopher Baines</p>

          <aside class="notes" data-markdown>
            **Hello**, my name is Chris.

            I'm going to set out some thoughts here about software,
            choices about how to use software, and how those relate to
            values like minimalism.

            In doing so, hopefully you'll be able to answer for
            yourself, the question "Is GNU Guix a minimal
            distribution?", and you'll have an idea of why that might
            matter to you.

            A little bit about me, I've been doing stuff in and around
            Guix for the last few years now, I first got involved
            around FOSDEM back in 2016.

            First though, if you haven't heard of Guix, here's a small
            introduction.
          </aside>
        </section>

        <section>
          <p class="fragment">Package manager</p>
          <p class="fragment">System</p>
          <p class="fragment">Software deployment toolkit</p>

          <aside class="notes" data-markdown>
            I often find Guix a little tricky to explain as a project,
            mainly because I feel you can do so much with it.

            The first thing to say though, is that Guix is a package
            manager.

            (Next)

            Packages in this case are software packages, and
            Guix can manage them, so Guix can help with things like
            installing software.

            Guix includes a large number of package definitions, over
            15,000 at the time I'm recording this talk, There's a
            whole range of software, written in many different
            languages, doing many different things.

            While Guix works on distributions using either Linux, or
            the GNU Hurd, Guix also provides the tooling and
            configuration to form a working operating system. This is
            normally referred to as a Guix system.

            (Next)

            So, Guix is a package manager, with lots of package
            definitions, and is also a distribution of GNU. That's
            quite a lot already. But, there's more.

            One not particularly specific, but apt description of Guix
            is a software deployment toolkit.

            (Next)

            The guix pack command is a clear example of this. This
            command allows you to take Guix packages, and wrap them up
            in to tarballs, Docker images, and squashfs images. In
            general, with the guix pack command can you use Guix to
            deploy software to systems which don't have the Guix tools
            available.

            Returning to the "Is GNU Guix a minimal distribution?"
            question. Surely with the description I've just given,
            Guix can't be considered minimal, there's so much going
            on!

            Well, I've described Guix, but what does minimalism mean,
            especially in the context of software.
          </aside>
        </section>

        <section>
          <h3>Minimal software</h3>
          <p class="fragment fade-in-then-semi-out">Smaller systems that take less resources<br> and consume less energy</p>
          <p class="fragment fade-in-then-semi-out">Secure systems that are easy to understand</p>

          <aside class="notes" data-markdown>
            I think the properties set out in the call for papers for
            the Declarative and Minimalistic Computing devroom are
            pretty good, so that's what I'm going to paraphrase here.

            (Next)

            Firstly, smaller systems generally take less resources and
            consume less energy. So resources in this context are
            things like storage space and RAM.

            (Next)

            The second is: secure systems that are easy to understand.

            Building on this, there's another perspective on
            minimalism I want to consider.
          </aside>
        </section>

        <section>
          <h4>Unix philosophy, point 1</h4>
          <blockquote>
            Make each program do one thing well. To do a new job,
            build afresh rather than complicate old programs by adding
            new "features".
          </blockquote>

          <aside class="notes" data-markdown>
            The Unix philosophy is a few ideas about building software
            and systems, it's from a while back, but still pretty
            relevant today. I'm just going to mention the first of the
            4 points.

            That point is: make each program do one thing well. To do
            a new job, build afresh rather than complicate old
            programs by adding new "features".

            Focusing on the "make each program do one thing well", I
            think that's really relevant, especially in the context of
            minimalism, but how do you determine if a program is doing
            one thing?

            Fundamentally, all tasks can be broken down, and you can
            see this in the way that software is often
            written. Programs can be broken down in to small reusable
            parts, often called procedures or functions that do "one
            thing", and the code within those functions can be further
            broken down with each line doing "one thing".

            If you're familiar with writing software, you'll probably
            know that how you break down a problem in to code to
            tackle it is very important, not just for solving the
            problem, but also doing so in a maintainable manor.
          </aside>
        </section>

        <section>
          <h1 class="r-fit-text">Does Guix do one thing?</h2>

          <aside class="notes" data-markdown>
            Going back to the question of whether Guix is a minimal
            distribution, I think it's relevant to ask if Guix does
            one thing, and if so, what that is?

            The first way of answering this, is no, I listed some
            things that Guix is earlier, a package manager, a
            distribution, plus some tools like guix pack.

            But, I think there's a better perspective. I think the one
            problem Guix tackles is software deployment.
          </aside>
        </section>

        <section>
          <h1 class="r-fit-text" style="font-weight: normal;">Guix tackles the problem<br>of <strong>software deployment</strong></h2>

          <aside class="notes" data-markdown>
            Now I mean deployment here in a very general sense, often
            you deploy to some computer you're not sitting next to,
            but I think getting some software running on your local
            machine is deployment as well, you're still taking some
            software and making it work.

            Because Guix can be used to manage software, manage
            service configuration, configure whole systems and
            generate things like system images or software bundles in
            various forms, Guix can capably handle a broad range of
            software deployment tasks.

            These are tasks that in the past, would have probably been
            handled by separate tools. I think the consolidation that
            Guix provides is a step forward, and is something that
            just happens naturally over time.

            In computer hardware for example, features
            that you once would have had separate hardware for like
            sound cards or network cards have been consolidated in to
            motherboards. Aspects of motherboards have been
            consolidated in to processors, and this generally happens
            because the advantages outweigh the costs.

            To show this, rather than just state it, and highlight
            what's different about using Guix or an approach like it,
            I'm going to try and articulate what the opposite approach
            looks like.

            What happens if you don't treat software deployment as one
            problem, but as multiple smaller interrelated problems,
            and use multiple tools.

            For the last few years, I've been working with the Ruby on
            Rails web development framework, I also worked on
            packaging it for Guix, so I'm using this as my
            example.
          </aisde>
        </section>

        <section id="demo-slide" data-background-color="black">
          <asciinema-player
            id="demo-player"
            src="demo.cast"
            rows="26"
            speed="1.2"
            loop="true"
            font-size="medium"
          ></asciinema-player>

          <aside class="notes" data-markdown>
            This isn't something you should follow, I'm just trying to
            set the scene for what tackling a problem with minimal use
            of Guix might mean.

            I'm roughly following the "Installing Rails" section of
            the Getting started guide.

            First there are 4 prerequsites: Ruby, SQLite3, Node.js and
            Yarn. I'm going to use Guix to provide Ruby, Sqlite and
            Node. Guix doesn't yet have a package for Yarn, I'm going
            to install it with NPM. To try and limit the impact on the
            rest of my system, I'm using direnv to manage the
            environment.

            With Rubygems, I'm installing Rails. This gets me the
            rails command.

            Rubygems is the language specific package manager for Ruby.

            That's now finished, this recording is running at 1.2
            times speed so it doesn't take so long.

            I'm then running the command: rails new blog, which
            creates a new Rails app.

            This does a few interesting things, a second tool related
            to trying to manage Ruby gems appears, bundler. While
            Rubygems is a package management framework for Ruby,
            bundler is a tool to try and make sure Ruby applications
            run the same code on every machine.

            That's not the end of the package management going on
            though, the rails new command invokes yarn to install some
            packages, something called webpacker I believe, which
            pulls in roughly 600 packages through yarn.

            So, with the problem being installing Rails, there are a
            number of tools involved here, and it is possible to
            describe each as doing just one thing.

            Guix was used to install prerequsites, apart from
            yarn. npm was used to install yarn. Rubygems was used to
            install Rails, at least parts of it. Bundler came in to
            the mix, which provides a more strict way of using
            gems. Then finally yarn was used to install webpacker.

            So, what are the disadvantages of this fragmented
            approach?
          </aside>
        </section>

        <section class="dark-section" data-background-color="black">
          <h3>The fragmented approach</h3>
          <p class="fragment fade-in-then-semi-out">Time spent using multiple tools</p>
          <p class="fragment fade-in-then-semi-out">More state to manage</p>
          <p style="visibility: hidden;">Limited functionality due to lack of interoperation</p>
          <p style="visibility: hidden;">Raises the cost for diverse tooling</p>
          <p style="visibility: hidden;">Dependent on many tools</p>

          <aside class="notes" data-markdown>
            (Next)

            Firstly, you as the user are spending time dealing with
            several tools, 4 or 5 in this example, depending on how
            you count.

            They don't really interoperate, Rails runs bundler and
            yarn, but that's not really interoperation at the package
            manager level.

            (Next)

            You've also got lots of state to manage.

            To illustrate, here are I think some of the files that
            were created tracking state about what software I'm
            deploying for this Rails app.
          </aside>
        </section>

        <section class="dark-section" data-background-color="black">
          <h4>Gemfile</h4>
          <pre style="font-size: small;">
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '3.0.0'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.1.1'
# Use sqlite3 as the database for Active Record
gem 'sqlite3', '~> 1.4'
# Use Puma as the app server
gem 'puma', '~> 5.0'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 5.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.4', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 4.1.0'
  # Display performance information such as SQL time and flame graphs for each request in your browser.
  # Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
  gem 'rack-mini-profiler', '~> 2.0'
  gem 'listen', '~> 3.3'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 3.26'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
          </pre>

          <aside class="notes" data-markdown>
            The is a Gemfile, this is used by Bundler, which works on
            top of Rubygems.

            This file says something about the Ruby version, this is
            just a check. There's also a .ruby-version file that's
            been created, I'm unsure what the reason behind that is.

            This file lists the gems that are wanted, along with
            constraints for the dependency resolver.
          </aside>
        </section>
        <section class="dark-section" data-background-color="black">
          <h4>Gemfile.lock</h4>
          <pre style="font-size: small;">
GEM
  remote: https://rubygems.org/
  specs:
    actioncable (6.1.1)
      actionpack (= 6.1.1)
      activesupport (= 6.1.1)
      nio4r (~> 2.0)
      websocket-driver (>= 0.6.1)
    actionmailbox (6.1.1)
      actionpack (= 6.1.1)
      activejob (= 6.1.1)
      activerecord (= 6.1.1)
      activestorage (= 6.1.1)
      activesupport (= 6.1.1)
      mail (>= 2.7.1)
    actionmailer (6.1.1)
      actionpack (= 6.1.1)
      actionview (= 6.1.1)
      activejob (= 6.1.1)
      activesupport (= 6.1.1)
      mail (~> 2.5, >= 2.5.4)
      rails-dom-testing (~> 2.0)
    actionpack (6.1.1)
      actionview (= 6.1.1)
      activesupport (= 6.1.1)
      rack (~> 2.0, >= 2.0.9)
      rack-test (>= 0.6.3)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.0, >= 1.2.0)
    actiontext (6.1.1)
      actionpack (= 6.1.1)
      activerecord (= 6.1.1)
      activestorage (= 6.1.1)
      activesupport (= 6.1.1)
      nokogiri (>= 1.8.5)
    actionview (6.1.1)
      activesupport (= 6.1.1)
      builder (~> 3.1)
      erubi (~> 1.4)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.1, >= 1.2.0)
    activejob (6.1.1)
      activesupport (= 6.1.1)
      globalid (>= 0.3.6)
    activemodel (6.1.1)
      activesupport (= 6.1.1)
    activerecord (6.1.1)
      activemodel (= 6.1.1)
      activesupport (= 6.1.1)
    activestorage (6.1.1)
      actionpack (= 6.1.1)
      activejob (= 6.1.1)
      activerecord (= 6.1.1)
      activesupport (= 6.1.1)
      marcel (~> 0.3.1)
      mimemagic (~> 0.3.2)
    activesupport (6.1.1)
      concurrent-ruby (~> 1.0, >= 1.0.2)
      i18n (>= 1.6, < 2)
      minitest (>= 5.1)
      tzinfo (~> 2.0)
      zeitwerk (~> 2.3)
    addressable (2.7.0)
      public_suffix (>= 2.0.2, < 5.0)
    bindex (0.8.1)
    bootsnap (1.5.1)
      msgpack (~> 1.0)
    builder (3.2.4)
    byebug (11.1.3)
    capybara (3.34.0)
      addressable
      mini_mime (>= 0.1.3)
      nokogiri (~> 1.8)
      rack (>= 1.6.0)
      rack-test (>= 0.6.3)
      regexp_parser (~> 1.5)
      xpath (~> 3.2)
    childprocess (3.0.0)
    concurrent-ruby (1.1.7)
    crass (1.0.6)
    erubi (1.10.0)
    ffi (1.14.2)
    globalid (0.4.2)
      activesupport (>= 4.2.0)
    i18n (1.8.7)
      concurrent-ruby (~> 1.0)
    jbuilder (2.10.1)
      activesupport (>= 5.0.0)
    listen (3.4.0)
      rb-fsevent (~> 0.10, >= 0.10.3)
      rb-inotify (~> 0.9, >= 0.9.10)
    loofah (2.8.0)
      crass (~> 1.0.2)
      nokogiri (>= 1.5.9)
    mail (2.7.1)
      mini_mime (>= 0.1.1)
    marcel (0.3.3)
      mimemagic (~> 0.3.2)
    method_source (1.0.0)
    mimemagic (0.3.5)
    mini_mime (1.0.2)
    minitest (5.14.3)
    msgpack (1.3.3)
    nio4r (2.5.4)
    nokogiri (1.11.1-x86_64-linux)
      racc (~> 1.4)
    public_suffix (4.0.6)
    puma (5.1.1)
      nio4r (~> 2.0)
    racc (1.5.2)
    rack (2.2.3)
    rack-mini-profiler (2.3.0)
      rack (>= 1.2.0)
    rack-proxy (0.6.5)
      rack
    rack-test (1.1.0)
      rack (>= 1.0, < 3)
    rails (6.1.1)
      actioncable (= 6.1.1)
      actionmailbox (= 6.1.1)
      actionmailer (= 6.1.1)
      actionpack (= 6.1.1)
      actiontext (= 6.1.1)
      actionview (= 6.1.1)
      activejob (= 6.1.1)
      activemodel (= 6.1.1)
      activerecord (= 6.1.1)
      activestorage (= 6.1.1)
      activesupport (= 6.1.1)
      bundler (>= 1.15.0)
      railties (= 6.1.1)
      sprockets-rails (>= 2.0.0)
    rails-dom-testing (2.0.3)
      activesupport (>= 4.2.0)
      nokogiri (>= 1.6)
    rails-html-sanitizer (1.3.0)
      loofah (~> 2.3)
    railties (6.1.1)
      actionpack (= 6.1.1)
      activesupport (= 6.1.1)
      method_source
      rake (>= 0.8.7)
      thor (~> 1.0)
    rake (13.0.3)
    rb-fsevent (0.10.4)
    rb-inotify (0.10.1)
      ffi (~> 1.0)
    regexp_parser (1.8.2)
    rubyzip (2.3.0)
    sass-rails (6.0.0)
      sassc-rails (~> 2.1, >= 2.1.1)
    sassc (2.4.0)
      ffi (~> 1.9)
    sassc-rails (2.1.2)
      railties (>= 4.0.0)
      sassc (>= 2.0)
      sprockets (> 3.0)
      sprockets-rails
      tilt
    selenium-webdriver (3.142.7)
      childprocess (>= 0.5, < 4.0)
      rubyzip (>= 1.2.2)
    semantic_range (2.3.1)
    spring (2.1.1)
    sprockets (4.0.2)
      concurrent-ruby (~> 1.0)
      rack (> 1, < 3)
    sprockets-rails (3.2.2)
      actionpack (>= 4.0)
      activesupport (>= 4.0)
      sprockets (>= 3.0.0)
    sqlite3 (1.4.2)
    thor (1.0.1)
    tilt (2.0.10)
    turbolinks (5.2.1)
      turbolinks-source (~> 5.2)
    turbolinks-source (5.2.0)
    tzinfo (2.0.4)
      concurrent-ruby (~> 1.0)
    web-console (4.1.0)
      actionview (>= 6.0.0)
      activemodel (>= 6.0.0)
      bindex (>= 0.4.0)
      railties (>= 6.0.0)
    webdrivers (4.4.2)
      nokogiri (~> 1.6)
      rubyzip (>= 1.3.0)
      selenium-webdriver (>= 3.0, < 4.0)
    webpacker (5.2.1)
      activesupport (>= 5.2)
      rack-proxy (>= 0.6.1)
      railties (>= 5.2)
      semantic_range (>= 2.3.0)
    websocket-driver (0.7.3)
      websocket-extensions (>= 0.1.0)
    websocket-extensions (0.1.5)
    xpath (3.2.0)
      nokogiri (~> 1.8)
    zeitwerk (2.4.2)

PLATFORMS
  x86_64-linux

DEPENDENCIES
  bootsnap (>= 1.4.4)
  byebug
  capybara (>= 3.26)
  jbuilder (~> 2.7)
  listen (~> 3.3)
  puma (~> 5.0)
  rack-mini-profiler (~> 2.0)
  rails (~> 6.1.1)
  sass-rails (>= 6)
  selenium-webdriver
  spring
  sqlite3 (~> 1.4)
  turbolinks (~> 5)
  tzinfo-data
  web-console (>= 4.1.0)
  webdrivers
  webpacker (~> 5.0)

RUBY VERSION
   ruby 3.0.0p0

BUNDLED WITH
   2.2.3
          </pre>

          <aside class="notes" data-markdown>
            Next is the Gemfile.lock, this goes along with the
            Gemfile.

            The Gemfile is what you edit, and the Gemfile.lock is
            updated when the dependency resolver is run. It's a bit
            longer than can fit on this slide.
          </aside>
        </section>
        <section class="dark-section" data-background-color="black">
          <h4>package.json</h4>
          <pre style="font-size: small;">
{
  "name": "blog",
  "private": true,
  "dependencies": {
    "@rails/actioncable": "^6.0.0",
    "@rails/activestorage": "^6.0.0",
    "@rails/ujs": "^6.0.0",
    "@rails/webpacker": "5.2.1",
    "turbolinks": "^5.2.0"
  },
  "version": "0.1.0",
  "devDependencies": {
    "webpack-dev-server": "^3.11.1"
  }
}
          </pre>

          <aside class="notes" data-markdown>
            Switching tools, this is the package.json file which is
            used by NPM the Node package manager, and in this case,
            yarn, which was invoked as part of the rails new command.

            Like the Gemfile, this includes lists of packages, with
            constraints for a dependency resolver, just a different
            one from the one I mentioned previously for the gem
            dependencies.
          </aside>
        </section>
        <section class="dark-section" data-background-color="black">
          <h4>yarn.lock</h4>
          <pre style="font-size: small;">
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11":
  version "7.12.11"
  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
  integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==
  dependencies:
    "@babel/highlight" "^7.10.4"

"@babel/compat-data@^7.12.5", "@babel/compat-data@^7.12.7":
  version "7.12.7"
  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.7.tgz#9329b4782a7d6bbd7eef57e11addf91ee3ef1e41"
  integrity sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw==

"@babel/core@^7.11.1":
  version "7.12.10"
  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.10.tgz#b79a2e1b9f70ed3d84bbfb6d8c4ef825f606bccd"
  integrity sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==
  dependencies:
    "@babel/code-frame" "^7.10.4"
    "@babel/generator" "^7.12.10"
    "@babel/helper-module-transforms" "^7.12.1"
    "@babel/helpers" "^7.12.5"
    "@babel/parser" "^7.12.10"
    "@babel/template" "^7.12.7"
    "@babel/traverse" "^7.12.10"
    "@babel/types" "^7.12.10"
    convert-source-map "^1.7.0"
    debug "^4.1.0"
    gensync "^1.0.0-beta.1"
    json5 "^2.1.2"
    lodash "^4.17.19"
    semver "^5.4.1"
    source-map "^0.5.0"

"@babel/generator@^7.12.10", "@babel/generator@^7.12.11":
  version "7.12.11"
  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af"
  integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==
  dependencies:
    "@babel/types" "^7.12.11"
    jsesc "^2.5.1"
    source-map "^0.5.0"

"@babel/helper-annotate-as-pure@^7.10.4":
  version "7.12.10"
  resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz#54ab9b000e60a93644ce17b3f37d313aaf1d115d"
  integrity sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==
  dependencies:
    "@babel/types" "^7.12.10"

"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4":
  version "7.10.4"
  resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3"
  integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==
  dependencies:
    "@babel/helper-explode-assignable-expression" "^7.10.4"
    "@babel/types" "^7.10.4"

"@babel/helper-compilation-targets@^7.12.5":
  version "7.12.5"
  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz#cb470c76198db6a24e9dbc8987275631e5d29831"
  integrity sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==
  dependencies:
    "@babel/compat-data" "^7.12.5"
    "@babel/helper-validator-option" "^7.12.1"
    browserslist "^4.14.5"
    semver "^5.5.0"

"@babel/helper-create-class-features-plugin@^7.12.1":
  version "7.12.1"
  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz#3c45998f431edd4a9214c5f1d3ad1448a6137f6e"
  integrity sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==
  dependencies:
    "@babel/helper-function-name" "^7.10.4"
    "@babel/helper-member-expression-to-functions" "^7.12.1"
    "@babel/helper-optimise-call-expression" "^7.10.4"
    "@babel/helper-replace-supers" "^7.12.1"
    "@babel/helper-split-export-declaration" "^7.10.4"

"@babel/helper-create-regexp-features-plugin@^7.12.1":
  version "7.12.7"
  resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz#2084172e95443fa0a09214ba1bb328f9aea1278f"
  integrity sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==
  dependencies:
    "@babel/helper-annotate-as-pure" "^7.10.4"
    regexpu-core "^4.7.1"

"@babel/helper-define-map@^7.10.4":
  version "7.10.5"
  resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30"
  integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==
  dependencies:
    "@babel/helper-function-name" "^7.10.4"
    "@babel/types" "^7.10.5"
    lodash "^4.17.19"

"@babel/helper-explode-assignable-expression@^7.10.4":
  version "7.12.1"
  resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz#8006a466695c4ad86a2a5f2fb15b5f2c31ad5633"
  integrity sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA==
  dependencies:
    "@babel/types" "^7.12.1"

"@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.12.11":
  version "7.12.11"
  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz#1fd7738aee5dcf53c3ecff24f1da9c511ec47b42"
  integrity sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==
  dependencies:
    "@babel/helper-get-function-arity" "^7.12.10"
    "@babel/template" "^7.12.7"
    "@babel/types" "^7.12.11"

"@babel/helper-get-function-arity@^7.12.10":
  version "7.12.10"
  resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz#b158817a3165b5faa2047825dfa61970ddcc16cf"
  integrity sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==
  dependencies:
    "@babel/types" "^7.12.10"

"@babel/helper-hoist-variables@^7.10.4":
  version "7.10.4"
  resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e"
  integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==
  dependencies:
    "@babel/types" "^7.10.4"

"@babel/helper-member-expression-to-functions@^7.12.1", "@babel/helper-member-expression-to-functions@^7.12.7":
  version "7.12.7"
  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz#aa77bd0396ec8114e5e30787efa78599d874a855"
  integrity sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==
  dependencies:
    "@babel/types" "^7.12.7"

"@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.5":
  version "7.12.5"
  resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb"
  integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==
  dependencies:
    "@babel/types" "^7.12.5"

"@babel/helper-module-transforms@^7.12.1":
  version "7.12.1"
  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c"
  integrity sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==
  dependencies:
    "@babel/helper-module-imports" "^7.12.1"
    "@babel/helper-replace-supers" "^7.12.1"
    "@babel/helper-simple-access" "^7.12.1"
    "@babel/helper-split-export-declaration" "^7.11.0"
    "@babel/helper-validator-identifier" "^7.10.4"
    "@babel/template" "^7.10.4"
    "@babel/traverse" "^7.12.1"
    "@babel/types" "^7.12.1"
    lodash "^4.17.19"

"@babel/helper-optimise-call-expression@^7.10.4", "@babel/helper-optimise-call-expression@^7.12.10":
  version "7.12.10"
  resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz#94ca4e306ee11a7dd6e9f42823e2ac6b49881e2d"
  integrity sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==
  dependencies:
    "@babel/types" "^7.12.10"

"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
  version "7.10.4"
  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375"
  integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==

"@babel/helper-remap-async-to-generator@^7.12.1":
  version "7.12.1"
  resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz#8c4dbbf916314f6047dc05e6a2217074238347fd"
  integrity sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==
  dependencies:
    "@babel/helper-annotate-as-pure" "^7.10.4"
    "@babel/helper-wrap-function" "^7.10.4"
    "@babel/types" "^7.12.1"

"@babel/helper-replace-supers@^7.12.1":
  version "7.12.11"
  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz#ea511658fc66c7908f923106dd88e08d1997d60d"
  integrity sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==
  dependencies:
    "@babel/helper-member-expression-to-functions" "^7.12.7"
    "@babel/helper-optimise-call-expression" "^7.12.10"
    "@babel/traverse" "^7.12.10"
    "@babel/types" "^7.12.11"

"@babel/helper-simple-access@^7.12.1":
  version "7.12.1"
  resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz#32427e5aa61547d38eb1e6eaf5fd1426fdad9136"
  integrity sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==
  dependencies:
    "@babel/types" "^7.12.1"
          </pre>

          <aside class="notes" data-markdown>
            Like the Gemfile and Gemfile.lock, there's a corresponding
            yarn.lock file for the output of the dependency resolver.

            Interestingly, this is a lot larger than the Gemfile.lock,
            mostly as it tracks around 600 packages I think, and
            includes hashes to check integrity, which is a good
            feature.
          </aside>
        </section>

        <section class="dark-section" data-background-color="black">
          <h3>The fragmented approach</h3>
          <p class="revealed-fragment">Time spent using multiple tools</p>
          <p class="revealed-fragment">More state to manage</p>
          <p class="fragment fade-in-then-semi-out">Limited functionality due to lack of interoperation</p>
          <p class="fragment fade-in-then-semi-out">Raises the cost for diverse tooling</p>
          <p class="fragment fade-in-then-semi-out">Dependent on many tools</p>

          <aside class="notes" data-markdown>
            That's 4 files, the Gemfile, Gemfile.lock, package.json
            and yarn.lock. There's also Guix providing plenty of
            dependencies which I haven't described tracking.

            What I'm getting at here is that each of these tools has
            it's complexities, and by using multiple package managers
            at once, this complexity is shifted on to you, the user.

            (Next)

            Next I want to talk about the limitations this fragmented
            approach imposes.

            You've got the cost of two dependency resolvers involved
            here, and all the resulting state so you can attempt to
            reproduce the setup in the future and on different
            machines.

            You can't look at dependencies across these fragmented
            ecosystems though, the Rubygems resolver isn't going to
            pick gem versions that work with the libraries Guix is
            providing. Similarly, yarn isn't going to help you pick
            JavaScript libraries that will work with the Ruby code
            you've got.

            This is just one example of how this breakdown of the
            problem roughly along the lines of programming language
            makes it harder to provide a good user experience.

            (Next)

            All of this means you'll be discouraged from picking
            software that isn't available through the limited package
            managers you're already using. Ignoring Guix, and the wide
            range of software it provides, Rubygems and NPM aren't
            going to provide you with tools written in Python, or
            Rust, or Java for example.

            With this fractured approach to package management, you'll
            be discouraged from picking the best available tool if
            that's not available through the package managers you're
            using.

            (Next)

            Finally, there are risks being dependent on multiple
            tools. Bugs or security issues in these tools might impact
            you, and both Rubygems and NPM are dependent on remote
            package repositories. With these services, comes the
            potential for downtime that prevents deployments.

            So, with all of that said, is there an alternative?
          </aside>
        </section>

        <section>
          <h3>A minimal approach</h3>

          <p class="fragment fade-in-then-semi-out">Just one approach</p>
          <p class="fragment fade-in-then-semi-out">Declaritive and reproducible</p>
          <p class="fragment fade-in-then-semi-out">Powerful tooling</p>
          <p style="visibility: hidden;">Pick and choose from software regardless of language</p>
          <p style="visibility: hidden;">Reliable, with less risk</p>

          <aside class="notes" data-markdown>
            What would be a minimal approach to software deployment?

            (Next)

            Firstly, take a singular approach that works for all the
            software you're using. Then you're not spending time
            trying to manage the use and interaction of multiple
            tools.

            (Next)

            Then, the same principles that apply to state in a program
            apply to deploying software. Rather than running a
            dependency resolver, or even multiple dependency
            resolvers, and storing the results so that you can use
            that state later. Instead, declare what dependencies
            you're going to use in a concise and reproducible manor.

            Before starting to use Guix, I thought that dependency
            resolvers were the core part of package managers. Now I
            think in many cases, you're better off without trying to
            resolve dependencies in this manor, especially right when
            you're trying to install packages.

            (Next)

            I think it follows from taking one consolidated approach
            to software deployment, that tooling can be built around
            this that isn't limited by splitting down the problem
            along the lines of programming language.
          </aside>
        </section>

        <section>
          <!-- guix graph --type=references ruby-railties | fdp -Goverlap=2:prism -Gsplines=true -Tsvg -->
          <img src="ruby-railties.svg"/>
          <pre style="font-size: small; text-align: center;">
guix graph --type=references ruby-railties | fdp -Goverlap=2:prism -Gsplines=true -Tsvg</pre>

          <aside class="notes" data-markdown>
            As a small example of this, this is visualised output from
            the guix graph command for the ruby-railties package.

            You probably won't be able to read the text, but each box
            represents a built package output, and the lines represent
            references, so the dependencies between those package
            outputs.

            Because Guix has all the information about the
            relationships between the different packages, the Ruby
            packages on the left are joined on to things like Ruby
            itself which is implemented in C, and other non-Ruby
            packages to the top right.
          </aside>
        </section>

        <section>
          <h3>A minimal approach</h3>

          <p class="revealed-fragment">Just one approach</p>
          <p class="revealed-fragment">Declaritive and reproducible</p>
          <p class="revealed-fragment">Powerful tooling</p>
          <p class="fragment fade-in-then-semi-out">Pick and choose from software regardless of language</p>
          <p class="fragment fade-in-then-semi-out">Reliable, with less risk</p>

          <aside class="notes" data-markdown>
            I don't think being able to generate comprehensive graphs
            is a particularly enticing example of how this minimal
            approach is beneficial, but it is one of the more visual.

            I think the guix pack command is more generally relevant,
            being able to generate tarballs, Docker images and other
            software bundles makes it possible to get some of the
            benefits of using Guix, while not depending on Guix being
            available where you're deploying software to.

            The complete view of package dependencies is important for
            making Guix pack work, and work well, as that means that
            Guix knows what to put in the pack, and what it doesn't
            need to.

            For a more futuristic perspective, I'm really excited by
            the insights that Guix can provide about what software
            you're using, which is really important for keeping track
            of vulnerabilities that you might be impacted by. This is
            simplified by having one comprehensive source of
            information about what versions of what software you're
            using.

            (Next)

            Moving on, using a general purpose package manager that
            isn't specific to one language or one domain, means that
            you're no longer discouraged from using tools written in
            other languages, or with dependencies in different
            languages.

            (Next)

            Finally, with one approach to software deployment,
            hopefully it'll be easier to understand, and more
            reliable.

            Particularly with Guix, there's the Git repository to
            fetch updates to Guix itself and the package definitions,
            but that's not required when performing operations, and
            there's the option of using a mirror of the Git repository
            instead.
          </aside>
        </section>

        <section>
          <h3>Considering using Guix</h3>

          <p>Check the availability of packages</p>
          <p>Check architecture and platform support</p>

          <aside class="notes" data-markdown>
            Prior to saying even more positive stuff about Guix, I
            want to do some management of expectations.

            Guix has many high qualify package definitions, there's
            only a few cases where Guix doesn't build things from
            source out of necessity.

            Unfortunately, the trade off with this approach is that
            there is still much work remaining to package a lot more
            software.

            JavaScript in a particular area of deficiency, I'd expect
            most if not all of the 600 packages I mentioned earlier
            that yarn installed for the demo Rails app, are not
            packaged for Guix.

            Guix also only supports a number of architectures, so
            that's something to check as well.

            I don't want this to discourage you from considering Guix,
            but do keep this in mind when considering if you'll be
            able to use it immediately.

            Packaging software for Guix is a community effort, so you
            can help out if there are things you're missing.
          </aside>
        </section>

        <section>
          <h3>What sets Guix apart</h3>

          <p class="fragment fade-in-then-semi-out">Quality package definitions</p>
          <p class="fragment fade-in-then-semi-out">Work with source packages, or prebuilt substitutes</p>
          <p class="fragment fade-in-then-semi-out">Dependable</p>
          <p class="fragment fade-in-then-semi-out">Feature rich</p>

          <aside class="notes" data-markdown>
            Back now to what makes Guix so good for deploying
            software.

            (Next)

            As I mentioned before, the package definitions that Guix
            has are rigorous, build the software from source with only
            a few exceptions, and in most cases run tests against the
            built software.

            (Next)

            Guix is great at orchestrating building software from
            source, but this isn't something you necessarily want to
            be doing. This is where substitutes come in, they're
            litrally substitutes for building something locally.

            Guix provides a build farm that builds Guix packages for
            multiple architectures, and you can download these build
            substitutes. You can also build and distribute substitutes
            yourself with tools like guix publish.

            This point is also a notable difference from package
            managers mentioned previously. Rubygems doesn't have such
            a general approach for providing built software, and while
            that's not relevant for the vast majority of Ruby
            packages, there are some that require compiling native
            code upon installation, which can get fustrating when it
            happens again and again.

            Having just one package manager allows you to solve
            problems once, and solve them well.

            (Next)

            Guix is dependable.

            It has good security properties, commits are signed, and
            these signatures are checked when you pull in
            updates. Rollbacks are detected, which helps to prevent
            rollback attacks. Substitutes are signed, which provides
            some security when fetching substitutes.

            There's some security in building the software from source
            as well, you're at least then not trusting the source,
            Guix and whoever compiled the software, but instead just
            the source and Guix.

            Guix also goes without many of the features that make
            other package managers less secure. Arbitrary code within
            packages isn't executed when you install packages which is
            something that's possible with other package managers.

            Guix is also less dependent on network services compared
            with lots of other package managers, which removes that as
            a point of failure.

            (Next)

            Finally, the rich set of features that Guix has means that
            it can comprehensivly tackle software deployment
            problems. If you can avoid using a distro, a config
            management tool, several language specific package
            managers and tools for providing isolation, and replace
            all of that complexity with Guix, you can spend more time
            on doing whatever you're trying to do, rather than
            spending it trying to deploy software.
          </aside>
        </section>

        <section>
          <p>Is GNU Guix a minimal distribution</p>

          <div class="fragment">
            <h2>Yes</h2>

            <p>Use it to consolidate your approach to software deployment</p>
          </div>

          <aside class="notes" data-markdown>
            So, is GNU Guix a minimal distribution.

            Yes.

            You can use it to consolidate your approach to deploying
            software.

            If Guix has the packages and features you need, and you're
            not already using it, adopting it might save you time in
            the long run.

            Even if Guix doesn't yet have the packages or features you
            need, you might still be able to get some value by using
            it, and that'll maybe give you the encouragement to start
            contributing.
          </aside>
        </section>

        <section>
          <img style="margin: 0;" src="guix.svg"/> <h2>Get involved!</h2>

          <p>Talk to others on #guix on freenode</p>

          <p>
            For the manual, mailing lists, papers, blog posts and
            talks, go to <a href="https://guix.gnu.org/">
            https://guix.gnu.org/</a>
          </p>

          <aside class="notes" data-markdown>
            If you're interested in learning more, the Guix website is
            probably a good place for information.

            There are active mailing lists and an IRC channel.

            I'm really excited by the potential I see in Guix, and I
            hope you are now too.
          </aside>
        </section>
      </div>
    </div>

    <script src="dist/reveal.js"></script>
    <script src="plugin/notes/notes.js"></script>
    <script src="plugin/markdown/markdown.js"></script>
    <script src="plugin/highlight/highlight.js"></script>
    <script>
     // More info about initialization & config:
     // - https://revealjs.com/initialization/
     // - https://revealjs.com/config/
     Reveal.initialize({
       hash: true,

       controls: false,
       progress: false,

       transition: 'none',

       margin: 0.12,

       showNotes: true,

       // Learn about plugins: https://revealjs.com/plugins/
       plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
     });

     var demoSlide = document.getElementById('demo-slide');
     Reveal.on( 'slidechanged', event => {
       if (event.currentSlide == demoSlide) {
         console.log("Playing demo");
         document.getElementById('demo-player').play();
       }
     });
    </script>
    <script src="js/asciinema-player.js"></script>
  </body>
</html>