summaryrefslogtreecommitdiffstats
path: root/articles/index.xml
blob: 6298845528f3ef00fcd8a4e0793569b242e078bb (plain) (blame)
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
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Articles on Nine Nines</title>
    <link>https://ninenines.eu/articles/</link>
    <description>Recent content in Articles on Nine Nines</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 29 Aug 2016 00:00:00 +0100</lastBuildDate>
    <atom:link href="https://ninenines.eu/articles/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Mailing list archived</title>
      <link>https://ninenines.eu/articles/ml-archives/</link>
      <pubDate>Mon, 29 Aug 2016 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/ml-archives/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The &lt;a href=&#34;https://ninenines.eu/archives/extend&#34;&gt;old mailing list archives&lt;/a&gt; have been
added to the site, mainly for referencing purposes.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The mailing list has been shut down and all personal information
has been deleted.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;If you need help with a project, consider either opening a ticket
on that project&amp;#8217;s issues tracker or going through the community
channels (erlang-questions, #ninenines or #erlang on Freenode).&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Prefer tickets; often when people have issues it highlights an
underlying problem in the project or its documentation.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Thanks.&lt;/p&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Website update</title>
      <link>https://ninenines.eu/articles/website-update/</link>
      <pubDate>Sat, 02 Apr 2016 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/website-update/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Last week-end I updated the Nine Nines website.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I switched to &lt;a href=&#34;http://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;. The site is
now built from &lt;a href=&#34;http://asciidoc.org/&#34;&gt;Asciidoc&lt;/a&gt;
documents. You probably saw me switch to Asciidoc
for documentation this past year. This is the
natural conclusion to that story. The great thing
is that with a little bit of Makefile magic I can
just copy the documentation files into Hugo and
poof, they appear on the website.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I am very happy with that new setup. I can now
post my thoughts again. Woo! Expect regular posts
from now on. I will try to replace my long series
of tweets with posts.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The sections have been rearranged. There used to
be a separate training section; now
&lt;a href=&#34;https://ninenines.eu/services&#34;&gt;all my services&lt;/a&gt; are described in
one page. I have also clarified my areas of
expertise. There used to be confusion in the past,
so now it should be clearer that I am not a
distributed systems expert.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;On that note, if you are looking for my
services right now, I&amp;#8217;m not available. I&amp;#8217;ll have
to work 7 days a week for a while. Try again in a
couple months. More on that in a future post.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The &lt;a href=&#34;https://ninenines.eu/docs&#34;&gt;documentation&lt;/a&gt; becomes a first class
citizen. Bullet and Cowlib don&amp;#8217;t have proper
documentation&amp;#8230; yet. I have started working on the
Cowlib documentation, and Bullet shouldn&amp;#8217;t take too
long. All these projects will be documented when
Cowboy gets to 2.0, and will all be supported
equally. Note that the Cowboy 1.0 documentation
still has the old website templates and links.
Don&amp;#8217;t worry about it.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The mailing lists link has been removed. I did
announce a few months back that mailing lists were
going to go. They&amp;#8217;re still up right now, but not
for long. I am planning to put the archives
read-only, link to them from a future post and
be done with it. If you have a question, open a
ticket on Github. Then I can just decide to leave
the ticket open if I want to do improvements based
on your feedback.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I have replaced most of the &#34;we&#34; by &#34;I&#34;. I am
a one-man company right now. Have been for a while.
Doesn&amp;#8217;t make sense to keep a facade. I want to be
close to users, not put a barrier between us.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The RSS changed. The old link doesn&amp;#8217;t work anymore.
The new link is at &lt;a href=&#34;https://ninenines.eu/index.xml&#34;&gt;/index.xml&lt;/a&gt;,
or &lt;a href=&#34;https://ninenines.eu/articles/index.xml&#34;&gt;/articles/index.xml&lt;/a&gt;
if you only care about my posts. I guess that&amp;#8217;s the
one most people want.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I still have some tweaks to do, but it will take a
while. My long term plan is to remove Bootstrap, use
vanilla CSS and as little JS as possible. The reason
for that is that it&amp;#8217;s cheaper than upgrading libraries
every few years. Life is too short to spend it
upgrading JS libraries.&lt;/p&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>The Erlanger Playbook September 2015 Update</title>
      <link>https://ninenines.eu/articles/erlanger-playbook-september-2015-update/</link>
      <pubDate>Wed, 02 Sep 2015 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/erlanger-playbook-september-2015-update/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;An update to The Erlanger Playbook is now available!&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The Erlanger Playbook is a book about software development using
Erlang. It currently covers all areas from the conception, design,
the writing of code, documentation and tests.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The book is still a work in progress. Future topics will include
refactoring, debugging and tracing, benchmarking, releases, community
management (for open source projects).&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This update fixes a number of things and adds two chapters: IOlists
and Erlang building blocks.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Learn more about &lt;a href=&#34;https://ninenines.eu/articles/erlanger-playbook&#34;&gt;The Erlanger Playbook&lt;/a&gt;!&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This is a self-published ebook. The base price is 50€. All proceeds
will be used to allow me to work on open source full time.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Thank you for helping me helping you help us all!&lt;/p&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>The Erlanger Playbook</title>
      <link>https://ninenines.eu/articles/erlanger-playbook/</link>
      <pubDate>Thu, 18 Jun 2015 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/erlanger-playbook/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I am proud to announce the pre-release of The Erlanger Playbook.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The Erlanger Playbook is a book about software development using
Erlang. It currently covers all areas from the conception, design,
the writing of code, documentation and tests.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The book is still a work in progress. Future topics will include
refactoring, debugging and tracing, benchmarking, releases, community
management (for open source projects).&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The following sections are currently available:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;ulist&#34;&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
About this book; Future additions
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
&lt;em&gt;Workflow:&lt;/em&gt; Think; Write; Stay productive
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
&lt;em&gt;Documentation:&lt;/em&gt; On documentation; Tutorials; User guide; Manual
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
&lt;em&gt;Code:&lt;/em&gt; Starting a project; Version control; Project structure; Code style; Best practices; Special processes
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
&lt;em&gt;Tests:&lt;/em&gt; On testing; Success typing analysis; Manual testing; Unit testing; Functional testing
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Read a preview: &lt;a href=&#34;https://ninenines.eu/res/erlanger-preview.pdf&#34;&gt;Special processes&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The book is currently just shy of 100 pages. The final version
of the book is planned to be between 200 and 250 pages.
A print version of the book will be considered once the final
version gets released. The printed book is &lt;strong&gt;not&lt;/strong&gt; included
in the price.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This is a self-published book. The base price is 50€. All proceeds
will be used to allow me to work on open source full time.&lt;/p&gt;&lt;/div&gt;
&lt;form action=&#34;https://www.paypal.com/cgi-bin/webscr&#34; method=&#34;post&#34; target=&#34;_top&#34;&gt;
&lt;input type=&#34;hidden&#34; name=&#34;cmd&#34; value=&#34;_s-xclick&#34;&gt;
&lt;input type=&#34;hidden&#34; name=&#34;hosted_button_id&#34; value=&#34;9M44HJCGX3GVN&#34;&gt;
&lt;input type=&#34;image&#34; src=&#34;https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif&#34; border=&#34;0&#34; name=&#34;submit&#34; alt=&#34;PayPal - The safer, easier way to pay online!&#34;&gt;
&lt;img alt=&#34;&#34; border=&#34;0&#34; src=&#34;https://www.paypalobjects.com/fr_FR/i/scr/pixel.gif&#34; width=&#34;1&#34; height=&#34;1&#34;&gt;
&lt;/form&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;You are more than welcome to pay extra by using this second button.
It allows you to set the price you want. Make sure to set it to at least
50€ to receive the book.&lt;/p&gt;&lt;/div&gt;
&lt;form action=&#34;https://www.paypal.com/cgi-bin/webscr&#34; method=&#34;post&#34; target=&#34;_top&#34;&gt;
&lt;input type=&#34;hidden&#34; name=&#34;cmd&#34; value=&#34;_s-xclick&#34;&gt;
&lt;input type=&#34;hidden&#34; name=&#34;hosted_button_id&#34; value=&#34;BBW9TR9LBK8C2&#34;&gt;
&lt;input type=&#34;image&#34; src=&#34;https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif&#34; border=&#34;0&#34; name=&#34;submit&#34; alt=&#34;PayPal - The safer, easier way to pay online!&#34;&gt;
&lt;img alt=&#34;&#34; border=&#34;0&#34; src=&#34;https://www.paypalobjects.com/fr_FR/i/scr/pixel.gif&#34; width=&#34;1&#34; height=&#34;1&#34;&gt;
&lt;/form&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Make sure to provide a valid email address.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;There will be a &lt;strong&gt;delay&lt;/strong&gt; between payment and sending of the book.
This process is currently manual.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;As the book is a pre-release, feedback is more than welcome. You can
send your comments to erlanger@ this website.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The plan is to add about 20 pages every month until it is completed.
You will receive updates to the book for free as soon as they are available.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Huge thanks for your interest in buying this book!&lt;/p&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Validating UTF-8 binaries with Erlang</title>
      <link>https://ninenines.eu/articles/erlang-validate-utf8/</link>
      <pubDate>Fri, 06 Mar 2015 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/erlang-validate-utf8/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Yesterday I pushed Websocket permessage-deflate to
Cowboy master. I also pushed
&lt;a href=&#34;https://github.com/ninenines/cowlib/commit/7e4983b70ddf8cedb967e36fba6a600731bdad5d&#34;&gt;a
change in the way the code validates UTF-8 data&lt;/a&gt;
(required for text and close frames as per the spec).&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;When looking into why the permessage-deflate tests
in autobahntestsuite were taking such a long time, I
found that autobahn is using an adaptation of the
algorithm named &amp;lt;a href=&#34;http://bjoern.hoehrmann.de/utf-8/decoder/dfa/&#34;&amp;gt;Flexible
and Economical UTF-8 Decoder&amp;lt;/a&amp;gt;. This is the C99
implementation:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// Copyright (c) 2008-2009 Bjoern Hoehrmann &amp;lt;[email protected]&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.&lt;/span&gt;&lt;/span&gt;

&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;#define&lt;/span&gt;&lt;/span&gt; UTF8_ACCEPT &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;#define&lt;/span&gt;&lt;/span&gt; UTF8_REJECT &lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;

&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;static&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;const&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #008080&#34;&gt;uint8_t&lt;/span&gt; utf8d&lt;span style=&#34;color: #990000&#34;&gt;[]&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #FF0000&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// 00..1f&lt;/span&gt;&lt;/span&gt;
  &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// 20..3f&lt;/span&gt;&lt;/span&gt;
  &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// 40..5f&lt;/span&gt;&lt;/span&gt;
  &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// 60..7f&lt;/span&gt;&lt;/span&gt;
  &lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// 80..9f&lt;/span&gt;&lt;/span&gt;
  &lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// a0..bf&lt;/span&gt;&lt;/span&gt;
  &lt;span style=&#34;color: #993399&#34;&gt;8&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;8&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// c0..df&lt;/span&gt;&lt;/span&gt;
  &lt;span style=&#34;color: #993399&#34;&gt;0xa&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x4&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// e0..ef&lt;/span&gt;&lt;/span&gt;
  &lt;span style=&#34;color: #993399&#34;&gt;0xb&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x6&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x6&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x6&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x5&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x8&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x8&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x8&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x8&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x8&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x8&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x8&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x8&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x8&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x8&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x8&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// f0..ff&lt;/span&gt;&lt;/span&gt;
  &lt;span style=&#34;color: #993399&#34;&gt;0x0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x5&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x8&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x7&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x4&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x6&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0x1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// s0..s0&lt;/span&gt;&lt;/span&gt;
  &lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// s1..s2&lt;/span&gt;&lt;/span&gt;
  &lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// s3..s4&lt;/span&gt;&lt;/span&gt;
  &lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// s5..s6&lt;/span&gt;&lt;/span&gt;
  &lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;// s7..s8&lt;/span&gt;&lt;/span&gt;
&lt;span style=&#34;color: #FF0000&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;;&lt;/span&gt;

uint32_t inline
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;decode&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;(&lt;/span&gt;uint32_t&lt;span style=&#34;color: #990000&#34;&gt;*&lt;/span&gt; state&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; uint32_t&lt;span style=&#34;color: #990000&#34;&gt;*&lt;/span&gt; codep&lt;span style=&#34;color: #990000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color: #008080&#34;&gt;uint32_t&lt;/span&gt; byte&lt;span style=&#34;color: #990000&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color: #FF0000&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color: #008080&#34;&gt;uint32_t&lt;/span&gt; type &lt;span style=&#34;color: #990000&#34;&gt;=&lt;/span&gt; utf8d&lt;span style=&#34;color: #990000&#34;&gt;[&lt;/span&gt;byte&lt;span style=&#34;color: #990000&#34;&gt;];&lt;/span&gt;

  &lt;span style=&#34;color: #990000&#34;&gt;*&lt;/span&gt;codep &lt;span style=&#34;color: #990000&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;(*&lt;/span&gt;state &lt;span style=&#34;color: #990000&#34;&gt;!=&lt;/span&gt; UTF8_ACCEPT&lt;span style=&#34;color: #990000&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;?&lt;/span&gt;
    &lt;span style=&#34;color: #990000&#34;&gt;(&lt;/span&gt;byte &lt;span style=&#34;color: #990000&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;0x3fu&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;(*&lt;/span&gt;codep &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;6&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt;
    &lt;span style=&#34;color: #990000&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0xff&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; type&lt;span style=&#34;color: #990000&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;(&lt;/span&gt;byte&lt;span style=&#34;color: #990000&#34;&gt;);&lt;/span&gt;

  &lt;span style=&#34;color: #990000&#34;&gt;*&lt;/span&gt;state &lt;span style=&#34;color: #990000&#34;&gt;=&lt;/span&gt; utf8d&lt;span style=&#34;color: #990000&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;256&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;*&lt;/span&gt;state&lt;span style=&#34;color: #990000&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;16&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;+&lt;/span&gt; type&lt;span style=&#34;color: #990000&#34;&gt;];&lt;/span&gt;
  &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;return&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;*&lt;/span&gt;state&lt;span style=&#34;color: #990000&#34;&gt;;&lt;/span&gt;
&lt;span style=&#34;color: #FF0000&#34;&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And this is the Erlang implementation I came up with:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;font-style: italic&#34;&gt;&lt;span style=&#34;color: #9A1900&#34;&gt;%% This function returns 0 on success, 1 on error, and 2..8 on incomplete data.&lt;/span&gt;&lt;/span&gt;
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;State&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;State&lt;/span&gt;;
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;128&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;128&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;128&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;5&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;128&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;128&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;8&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;128&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;5&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;6&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;192&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;192&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;4&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;192&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;6&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;192&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;192&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;194&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;224&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;224&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;4&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;225&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;237&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;237&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;5&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;=:=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;238&lt;/span&gt;; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;=:=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;239&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;240&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;6&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;=:=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;241&lt;/span&gt;; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;=:=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;242&lt;/span&gt;; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;=:=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;243&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;244&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;8&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;_&lt;/span&gt;, &lt;span style=&#34;color: #990000&#34;&gt;_&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Does it look similar to you? So how did we get there?&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I started with a naive implementation of the original. First, we
don&amp;#8217;t need the codepoint calculated and extracted for our validation
function. We just want to know the data is valid, so we only need to
calculate the next state. Then, the only thing we needed to be careful
about was that tuples are 1-based, and that we need to stop processing
the binary when we get the state 1 or when the binary is empty.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;State&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;State&lt;/span&gt;;
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;_&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;;
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;State&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;element&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #993399&#34;&gt;257&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;State&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;16&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;element&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;?UTF8D&lt;/span&gt;&lt;/span&gt;), &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;?UTF8D&lt;/span&gt;&lt;/span&gt;))&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The macro &lt;code&gt;?UTF8D&lt;/code&gt; is the tuple equivalent of the C array
in the original code.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Compared to our previous algorithm, this performed about the same.
In some situations a little faster, in some a little slower. In other words,
not good enough. But because this new algorithm allows us to avoid a binary
concatenation this warranted looking further.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;It was time to step into crazy land.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Erlang is very good at pattern matching, even more so than doing some
arithmetic coupled by fetching elements from a tuple. So I decided I was
going to write all possible clauses for all combinations of &lt;code&gt;C&lt;/code&gt;
and &lt;code&gt;State&lt;/code&gt;. And by write I mean generate.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;So I opened my Erlang shell, defined the variable &lt;code&gt;D&lt;/code&gt; to be
the tuple &lt;code&gt;?UTF8D&lt;/code&gt; with its 400 elements, and then ran the
following expression (after a bit of trial and error):&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;color: #993399&#34;&gt;16&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;file:write_file&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #FF0000&#34;&gt;&#34;out.txt&#34;&lt;/span&gt;,
        [&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;io_lib:format&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #FF0000&#34;&gt;&#34;validate_utf8(&amp;lt;&amp;lt; ~p, Rest/bits &amp;gt;&amp;gt;, ~p) -&amp;gt; ~p;~n&#34;&lt;/span&gt;,
                [&lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;S&lt;/span&gt;, &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;element&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #993399&#34;&gt;257&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;S&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;16&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;element&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;D&lt;/span&gt;), &lt;span style=&#34;color: #009900&#34;&gt;D&lt;/span&gt;)])
                        || &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;lists:seq&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color: #993399&#34;&gt;255&lt;/span&gt;), &lt;span style=&#34;color: #009900&#34;&gt;S&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;lists:seq&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color: #993399&#34;&gt;8&lt;/span&gt;)])&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;
&lt;span style=&#34;color: #FF6600&#34;&gt;ok&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The result is a 2304 lines long file, containing 2304 clauses.
People who pay attention to what I say on Twitter will remember
I said something around 3000 clauses, but that was just me not
using the right number of states in my estimate.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;There was a little more work to be done on this generated
code that I did using regular expressions. We need to recurse
when the resulting state is not 1. We also need to stop when
the binary is empty, making it the 2305th clause.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Still, 2305 is a lot. But hey, the code did work, and faster
than the previous implementation too! But hey, perhaps I could
find a way to reduce its size.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Removing all the clauses that return 1 and putting a catch-all
clause at the end instead reduced the number to about 500, and
showed that many clauses were similar:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;5&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;6&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;But also:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;157&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;157&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;157&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;5&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;157&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;6&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;157&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;158&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;158&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;158&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;5&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;158&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;6&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;158&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;);&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Patterns, my favorites!&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;A little more time was spent to edit the 500 or so clauses into
smaller equivalents, testing that performance was not impacted, and
comitting the result.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The patterns above can be found here in the resulting function:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;128&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;color: #990000&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;5&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;6&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;bits&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;7&lt;/span&gt;) &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;when&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;144&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;C&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;160&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;validate_utf8&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Rest&lt;/span&gt;, &lt;span style=&#34;color: #993399&#34;&gt;3&lt;/span&gt;);
&lt;span style=&#34;color: #990000&#34;&gt;...&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I hope you enjoyed this post.&lt;/p&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>On open source</title>
      <link>https://ninenines.eu/articles/on-open-source/</link>
      <pubDate>Fri, 05 Sep 2014 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/on-open-source/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Last week I read a great article
&lt;a href=&#34;http://videlalvaro.github.io/2014/08/on-contributing-to-opensource.html&#34;&gt;on
contributing to open source&lt;/a&gt; by Alvaro Videla. He makes
many great points and I am in agreement with most of it.
This made me want to properly explain my point of view with
regard to open source and contributions. Unlike most open
source evangelism articles I will not talk about ideals or
any of that crap, but rather my personal feelings and
experience.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I have been doing open source work for quite some time.
My very first open source project was a graphics driver
for (the very early version of) the PCSX2 emulator. That
was more than ten years ago, and there
&lt;a href=&#34;http://ngemu.com/threads/gstaris-0-6.30469/&#34;&gt;isn&amp;#8217;t
much left to look at today&lt;/a&gt;. This was followed by a
&lt;a href=&#34;https://github.com/extend/wee&#34;&gt;PHP framework&lt;/a&gt;
(started long before Zend Framework was even a thing) and
a few other small projects. None of them really took off.
It&amp;#8217;s alright, that&amp;#8217;s pretty much the fate of most open
source projects. You spend a lot of work and sweat and
get very little in return from others.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This sounds harsh but this is the reality of all open
source projects. If you are thinking of building a project
and releasing it as open source, you should be prepared
for that. This is how most of your projects will feel like.
Don&amp;#8217;t release a project as open source thinking everyone
will pat you on the back and cheer, this won&amp;#8217;t happen. In
fact if your project is a too small improvement over existing
software, what many people will do is say you have NIH
syndrome, regardless of the improvement you bring. So you
need not to rely on other people in order to get your
enjoyment out of building open source software.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;In my case I get enjoyment from thinking about problems
that need solving. Often times the problems are already
solved, but nevermind that, I still think about them and
sometimes come up with something I feel is better and then
write code for it. Writing code is also fun, but not as
fun as using my brain to imagine solutions.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;You don&amp;#8217;t need thousands of users to do that. So are
users worthless to me then? No, of course not. In fact
they are an important component: they bring me problems
that need solving. So users are very important to me.
But that&amp;#8217;s not the only reason.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I got lucky that the Cowboy project became popular.
And seeing it be this popular, and some of my other projects
also do quite well, made me believe I could perhaps work
full time on open source. If I can work full time then
I can produce better software. What I had one hour to
work on before I can now spend a day on, and experiment
until I am satisfied. This is very useful because that
means I can get it almost right from the beginning, and
avoid the million API breaking changes that occured
before Cowboy 1.0 was released.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;To be able to work full time on open source however,
I need money. This is a largely unspoken topic of open
source work. The work is never free. You can download the
product for free, but someone has to pay for the work
itself. Life is unfortunately not free.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Large projects and some lucky people have their work
sponsored by their employers. Everyone else has to deal
with it differently. In my case I was sponsored for a
while by the &lt;a href=&#34;http://leo-project.net/leofs/&#34;&gt;LeoFS&lt;/a&gt;
project, but that ended. I also had the Farwest fundraiser,
which was a success, although the project stalled after that.
(Fear not, as Farwest will make a comeback as a conglomerate
of Web development projects in the future.) After that I set
up the &lt;a href=&#34;http://ninenines.eu/support/&#34;&gt;sponsoring scheme&lt;/a&gt;,
which I can proudly say today brings in enough money to
cover my food and shelter. Great!&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This is a start, but it&amp;#8217;s of course not enough. Life
is a little more than food and shelter, and so I am still
looking for sponsors. This is not a very glorious experience,
as I am essentially looking for scraps that companies can
throw away. Still, if a handful more companies were doing
that, not only would I be able to live comfortably, but I
would also be able to stop worrying about the future as I
could put money on the side for when it gets rough.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;A few companies giving me some scrap money so I could
live and work independently is by far the most important
thing anyone can do to help my projects, including Cowboy.
Yes, they&amp;#8217;re even more important than code contributions,
bug reports and feedback. Because this money gives me the
time I need to handle the code contributions, bug reports
and feedback.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;If Cowboy or another project is a large part of your
product or infrastructure, then the best thing you can do
is become a sponsor. The second best is opening tickets
and/or providing feedback. The third best is providing
good code contributions.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I will not expand on the feedback part. Feedback is
very important, and even just a high five or a retweet
is already good feedback. It&amp;#8217;s not very complicated.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I want to expand a little on code contributions
however. Not long ago I ran across the term &#34;patch bomb&#34;
which means dropping patches and expecting the project
maintainers to merge them and maintain them. I receive
a lot of patches, and often have to refuse them. Causes
for refusal vary. Some patches only benefit the people
who submitted them (or a very small number of people).
Some patches are not refined enough to be included.
Others are out of scope of the project. These are some
of the reasons why I refuse patches. Having limited
time and resources, I have to focus my efforts on the
code used by the larger number of users. I have to
prioritize patches from submitters who are reactive
and address the issues pointed out. And I have to plainly
refuse other patches.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I believe this wraps up my thoughts on open source.
Overall I had a great experience, the Erlang community
being nice and understanding of the issues at hand in
general. And if the money problem could be solved soon,
then I would be one of the luckiest and happiest open
source developer on Earth.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Think about it the next time you see a donation button
or a request for funds or sponsoring. You can considerably
improve an open source developer&amp;#8217;s life with very little
of your company&amp;#8217;s money.&lt;/p&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>The story so far</title>
      <link>https://ninenines.eu/articles/the-story-so-far/</link>
      <pubDate>Sat, 23 Aug 2014 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/the-story-so-far/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;As I am away from home with little to do (some call this
a vacation) I wanted to reflect a little on the story so far,
or how I arrived to Erlang and got to where I am now. The
raw personal experience. It&amp;#8217;ll be an article that&amp;#8217;s more
about social aspect, communities and marketing a project than
technical considerations. As a period piece, it will also
allow me to reflect on the evolution of Erlang in recent
years.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Once upon a time-- Okay this isn&amp;#8217;t a fairy tale. The story
begins with a short chapter in 2010. The year 2010 started
with a fairly major event in my life: the US servers for the
online game I stopped playing a few months before, but was
still involved with through its community, were closing. OMG!
Someone found a way to log packets and started working on a
private server; meanwhile the JP servers were still up. And
that&amp;#8217;s pretty much it.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Fast forward a few months and it became pretty clear that
the private server was going nowhere considering all the drama
surrounding it-- which is actually not unusual, but it was
more entertaining than average and the technical abilities of
people running the project were obviously lacking so I decided
to obtain those logged packets and look at things myself. I
didn&amp;#8217;t want to do a private server yet, I only wanted to take
a peek to see how things worked, and perhaps organize some
effort to document the protocol.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;There was 10GB of logs. I didn&amp;#8217;t have an easy to use
language to analyze them, and hex editors wouldn&amp;#8217;t cut it for
most purposes, so I had to look elsewhere. This was a good
opportunity to start learning this PHP killer I read about
before, which also happens to feature syntax for matching
binaries, called Erlang. To be perfectly honest I wouldn&amp;#8217;t
have touched the logs if I didn&amp;#8217;t have the added motivation
to play with and learn a new language.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;At the time it was pretty hard to learn Erlang. In my
experience there was Joe&amp;#8217;s book (which I always recommend
first as I believe it is the best to learn the Erlang side
of things; but falls a little short on OTP), and there was
about 5 chapters of LYSE. There were a couple other books
I never managed to get into (sorry guys), and there was also
a few interesting blogs, some of which I can&amp;#8217;t find anymore.
Finally the #erlang IRC community was there but I was strictly
lurking at the time.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;What a difference compared to 4 years later! (That&amp;#8217;s
today, by the way!) Now we have more books than I can
remember, tons of articles covering various aspects of the
language and platform, many targeting beginners but a good
number of them also about advanced topics. We even have a
free online book, LYSE, with more than 30 chapters covering
pretty much everything. Needless to say I never finished
reading LYSE as it got written slower than I learnt.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Back to 2010. I wrote a parser for the logs, and
aggregated those results into one CSV file per packet type
so I could open them in Gnumeric and aggregate some more,
but manually this time, and draw conclusions on the packet
structures. That was pretty easy. Even for a beginner.
Anyone can go from zero to that level in a day or two.
Then, having mastered binary pattern matching, I wanted
to learn some more Erlang, by making this aggregation
faster. What I had done before worked, but I wasn&amp;#8217;t going
to wait forever to process everything sequentially. So I
looked and found a project called &lt;code&gt;plists&lt;/code&gt; (still exists,
but not maintained AFAIK). I downloaded that project and
replaced my &lt;code&gt;lists:&lt;/code&gt; calls to &lt;code&gt;plists:&lt;/code&gt;.
Boom. In just a few minutes all logs were processed, and
I had learnt something new.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;It is particularly interesting to note that the lack of
a package manager or index never bothered me. Neither before
nor after learning Erlang. My experience with package
managers was mostly related to Ubuntu, a little Perl and
Python, and PHP&amp;#8217;s Pear. Let&amp;#8217;s just stay polite and say it
was always a terrible experience. So searching on the Web
didn&amp;#8217;t feel awkward, because even if I used a tool or
website I would have ended up doing a search or two anyway.
This is in contrast to the package index feature in
&lt;a href=&#34;https://github.com/ninenines/erlang.mk&#34;&gt;Erlang.mk&lt;/a&gt;,
which is meant to simplify specifying dependencies more
than anything: &lt;code&gt;DEPS = cowboy&lt;/code&gt;. It does not
attempt to solve any other problem, and will only attempt
to solve one extra problem in the near future, which is
the discovery of packages. So expect some kind of website
listing packages soon enough.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I want to use this parenthese to also point out that at
the time there was a very small number of projects out there,
at least compared to today. While you sometimes hear people
complain about lack of certain libraries, it is so much
better now than it was before! The situation improves very
quickly, so much that it&amp;#8217;s not going to be that big an issue
soon enough.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Wanting to know more about that game&amp;#8217;s protocol, in the
year 2010, I ended up starting to write more Erlang code to
simulate a server and use the server to query the client and
see what was happening, documenting the packets and so on.
This eventually lead to a larger project implementing more
and more until people got their hopes up for a revival of
the game, all the while the now competing original server
project died in a stream of drama and technical incompetence.
Of course, I ended up doing what any good Internet citizen
would do, I crushed people&amp;#8217;s hopes, but that&amp;#8217;s not important
to our story. The important part is that before giving up
on this project, I not only learnt a good deal of Erlang
and a little deal of OTP (which I did not touch until 6
months after I started with Erlang; see the paragraph
about learning material above), but I also had an intriguing
idea pop into my mind for what would become my greatest
success yet.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The giving up part was not easy. Having had financial
difficulties all year 2010 and part of 2009, I resolved
to travel back to Paris to try and make it. I ended up
sleeping in offices for 6 months, being hosted by a shady
person, and hearing my fair share of stories about
the dark side of business. While there I also worked for
another company with someone who would end up becoming
another high profile Erlang developer. The situation
slowly improved, I started taking part in the #erlang
IRC discussions, giving up my status of lurker and, a
few months into 2011, started working on the Apache killer
project: Cowboy.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This is the part where I probably should get accused of
racism and other fun things, but I never did. And I think
that speaks lots about the Erlang community. In all my time
writing Erlang code, I can count the number of conflicts I
had with other people on a single hand. This is the nicest
programming community I have ever seen, by far. And the
humblest too. The Erlang community feels like Japan. And
I love Japan. So I love the Erlang community. I can&amp;#8217;t say
this enough. This is something that stayed true for all
my time using Erlang, and despite the rise of alternative
languages that are not Japan the Erlang community has
remained very Japan.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The first published version of Cowboy was written in
two weeks. A little before those two weeks, during, and
a while after, pretty much everything I said on the
Internets was that Cowboy was going to be the greatest
HTTP server ever, that the other servers were problematic
(and just to be clear, Yaws was rarely if ever mentioned,
due to being in a perceived different league of &#34;full
featured servers&#34; while Cowboy was a &#34;lightweight server&#34;),
and that Cowboy will be the best replacement to a Mochiweb
or Misultin application. This, alongside a lot of time
spent on IRC telling people to use Cowboy when they were
asking for an HTTP server to use, probably made me sound
very annoying. But it worked, and Cowboy started getting
its first users, despite being only a few weeks old. Of
course, as soon as I got my very first user, I started
claiming Cowboy had &#34;a lot of users&#34;.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Looking back today I would definitely find myself annoying,
this wasn&amp;#8217;t just an idle comment there. For about a year,
maybe a little more, all I ever said was that Cowboy was
the best. This probably made me a little dumber in the
process (as if I wasn&amp;#8217;t enough! I know). Being French, I
sometimes would also say things quite abruptly. To stay
polite, I probably sounded like an asshole. I learnt to
stop being so French over time thankfully.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I think what was most important to Cowboy at the time,
was three things. First, it felt fresh. It was new, had new
ideas, tried to do things differently and followed &#34;new&#34; old
best practices (the OTP way-- which was simply too obscure
for most people at the time). Second, it had me spending
all my time telling people to use it whenever they were
looking for an HTTP server. Third, it had me helping people
get started with it and guide them all the steps of the way.
Mostly because it didn&amp;#8217;t have a very good documentation, but
still, hand holding does wonders.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;To be able to help people every time they had a problem,
I did not spend all my days reading IRC. Instead I simply
made sure to be notified when someone said &lt;code&gt;cowboy&lt;/code&gt;.
The same way many people subscribe to alerts when their
company is mentioned in the news. Nothing fancy.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Time went on, Cowboy grew, or as some like to say,
completely destroyed the competition, and many people
eventually moved from Mochiweb and Misultin to Cowboy.
And then Roberto Ostinelli stopped Misultin development
and told everyone to move to Cowboy. This is the most
humble and selfless act I have ever seen in the programming
sphere, and I only have one thing to say about it: GG.
Thanks for the fish. He left me with the tasks of improving
Cowboy examples, documentation and strongly believed that
the Misultin interface was more user friendly out of all
the servers. So I added many examples, as many lines of
documentation as we have of code, and strongly believe
that Cowboy 2.0 will be the most user friendly interface
out of all servers. But only time will tell.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;With the rise of the project and the rise in the number
of users, my previous strategy (completely incidental, by
the way, and definitely not a well thought out plan to
become popular) stopped working. It was taking me too much
time. The important aspects slowly drifted. If I wanted to
support more users, I would have to spend less time with
each individual user. This was actually a hard problem.
You basically have to make people understand they can&amp;#8217;t
just come to you directly when they have a problem, they
have to follow proper channels. It becomes less personal,
and might be felt like you don&amp;#8217;t care about them anymore.
You have to hurt some people&amp;#8217;s feelings at this point. It
is quite unfortunate, and also quite difficult to do. There
is some unwritten rule that says early adopters deserve
more, but in the real world it never works like this. So
I probably hurt some people&amp;#8217;s feelings at some point. But
that&amp;#8217;s okay. Because even if you make sure to be as nice
as possible when you tell people to go through proper
channels from now on, some people will still get offended.
There&amp;#8217;s nothing you can do about it.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;From that point onward the important points about the
project was getting the documentation done, making sure
people knew about the proper channels to get help and
report issues, etc. Basically making myself less needed.
This is quite a contrast with the first days, but I believe
Cowboy made that transition successfully.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Not only did I win time by not having to hold hands with
everyone all the time (not that I didn&amp;#8217;t like it, but you
know, the sweat), but I also won time thanks to the increased
project popularity. Indeed, the more users you have, the more
annoying guys there are to tell people to use your project
and that it&amp;#8217;s the best and everything. Which is great. At
least, it&amp;#8217;s great if you don&amp;#8217;t pay too much attention to it.
Sometimes people will give an advice that is, in your opinion,
a bad advice. And that&amp;#8217;s okay. Don&amp;#8217;t intervene every time
someone gives a bad advice, learn to let it go. People will
figure it out. You learn by making mistakes, after all. Use
this extra time to make sure other people don&amp;#8217;t end up
giving the same bad advice instead. Fix the code or the
documentation that led to this mistake. Slowly improve the
project and make sure it doesn&amp;#8217;t happen again.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This is my story. So far, anyway.&lt;/p&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Cowboy 2.0 and query strings</title>
      <link>https://ninenines.eu/articles/cowboy2-qs/</link>
      <pubDate>Wed, 20 Aug 2014 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/cowboy2-qs/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Now that Cowboy 1.0 is out, I can spend some of my time thinking
about Cowboy 2.0 that will be released soon after Erlang/OTP 18.0.
This entry discusses the proposed changes to query string handling
in Cowboy.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Cowboy 2.0 will respond to user wishes by simplifying the interface
of the &lt;code&gt;cowboy_req&lt;/code&gt; module. Users want two things: less
juggling with the Req variable, and more maps. Maps is the only
dynamic key/value data structure in Erlang that we can match directly
to extract values, allowing users to greatly simplify their code as
they don&amp;#8217;t need to call functions to do everything anymore.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Query strings are a good candidate for maps. It&amp;#8217;s a list of
key/values, so it&amp;#8217;s pretty obvious we can win a lot by using maps.
However query strings have one difference with maps: they can have
duplicate keys.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;How are we expected to handle duplicate keys? There&amp;#8217;s no standard
behavior. It&amp;#8217;s up to applications. And looking at what is done in
the wild, there&amp;#8217;s no de facto standard either. While some ignore
duplicate keys (keeping the first or the last they find), others
require duplicate keys to end with &lt;code&gt;[]&lt;/code&gt; to automatically
put the values in a list, or even worse, languages like PHP even
allow you to do things like &lt;code&gt;key[something][other]&lt;/code&gt; and
create a deep structure for it. Finally some allow any key to have
duplicates and just gives you lists of key/values.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Cowboy so far had functions to retrieve query string values one
value at a time, and if there were duplicates it would return the
first it finds. It also has a function returning the entire list
with all duplicates, allowing you to filter it to get all of them,
and another function that returns the raw query string.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;What are duplicates used for? Not that many things actually.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;One use of duplicate keys is with HTML forms. It is common practice
to give all related checkboxes the same name so you get a list of
what&amp;#8217;s been checked. When nothing is checked, nothing is sent at all,
the key is not in the list.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Another use of duplicate keys is when generating forms. A good
example of that would be a form that allows uploading any number
of files. When you add a file, client-side code adds another field
to the form. Repeat up to a certain limit.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And that&amp;#8217;s about it. Of note is that HTML radio elements share
the same name too, but only one key/value is sent, so they are not
relevant here.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Normally this would be the part where I tell you how we solve
this elegantly. But I had doubts. Why? Because there&amp;#8217;s no good
solutions to solving only this particular problem.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I then stopped thinking about duplicate keys for a minute and
started to think about the larger problem.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Query strings are input data. They take a particular form,
and may be sent as part of the URI or as part of the request
body. We have other kinds of input data. We have headers and
cookies and the request body in various forms. We also have
path segments in URIs.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;What do you do with input data? Well you use it to do
something. But there is one thing that you almost always do
(and if you don&amp;#8217;t, you really should): you validate it and
you map it into Erlang terms.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Cowboy left the user take care of validation and conversion
into Erlang terms so far. Rather, it left the user take care
of it everywhere except one place. Guess where? That&amp;#8217;s right,
bindings.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;If you define routes with bindings then you have the option
to provide constraints. Constraints can be used to do two things:
validate the data and convert it in a more appropriate term. For
example if you use the &lt;code&gt;int&lt;/code&gt; constraint, Cowboy will
make sure the binding is an integer, and will replace the value
with the integer representation so that you can use it directly.
In this particular case it not only routes the URI, but also
validates and converts the bindings directly.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This is very relevant in the case of our duplicate keys,
because if we have a list with duplicates of a key, chances
are we want to convert that into a list of Erlang terms, and
also make sure that all the elements in this list are expected.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The answer to this particular problem is simple. We need a
function that will parse the query string and apply constraints.
But this is not all, there is one other problem to be solved.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The other problem is that for the user some keys are mandatory
and some are optional. Optional keys include the ones that
correspond to HTML checkboxes: if the key for one or more
checkbox is missing from the query string, we still want to
have an empty list in our map so we can easily match. Matching
maps is great, but not so much when values might be missing,
so we have to normalize this data a little.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This problem is solved by allowing a default value. If the
key is missing and a default exists, set it. If no default
exists, then the key was mandatory and we want to crash.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I therefore make a proposal for changing the query string
interface to three functions.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The first function already exists, it is &lt;code&gt;cowboy_req:qs(Req)&lt;/code&gt;
and it returns only the query string binary. No more Req returned.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The second function is a renaming of &lt;code&gt;cowboy_req:qs_vals(Req)&lt;/code&gt;
to something more explicit: &lt;code&gt;cowboy_req:parse_qs(Req)&lt;/code&gt;.
The new name implies that a parsing operation is done. It was implicit
and cached before. It will be explicit and not cached anymore now.
Again, no more Req returned.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The third function is the one I mentioned above. I think
the interface &lt;code&gt;cowboy_req:match_qs(Req, Fields)&lt;/code&gt; is
most appropriate. It returns a normalized map that is the same
regardless of optional fields being provided with the request,
allowing for easy matching. It crashes if something went wrong.
Still no Req returned.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I feel that this three function interface provides everything
one would need to comfortably write applications. You can get
low level and get the query string directly; you can get a list
of key/value binaries without any additional processing and do it
on your own; or you can get a processed map that contains Erlang
terms ready to be used.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I strongly believe that by democratizing the constraints to
more than just bindings, but also to query string, cookies and
other key/values in Cowboy, we can allow the developer to quickly
and easily go from HTTP request to Erlang function calls. The
constraints are reusable functions that can serve as guards
against unwanted data, providing convenience in the process.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Your handlers will not look like an endless series of calls
to get and convert the input data, they will instead be just
one call at the beginning followed by the actual application
logic, thanks to constraints and maps.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;handle&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Req&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;State&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt;
    #{&lt;span style=&#34;color: #FF6600&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;:=&lt;/span&gt;&lt;span style=&#34;color: #009900&#34;&gt;Name&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;email&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;:=&lt;/span&gt;&lt;span style=&#34;color: #009900&#34;&gt;Email&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;choices&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;:=&lt;/span&gt;&lt;span style=&#34;color: #009900&#34;&gt;ChoicesList&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;remember_me&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;:=&lt;/span&gt;&lt;span style=&#34;color: #009900&#34;&gt;RememberMe&lt;/span&gt;} &lt;span style=&#34;color: #990000&#34;&gt;=&lt;/span&gt;
        &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;cowboy_req:match_qs&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Req&lt;/span&gt;, [
            &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;name&lt;/span&gt;&lt;/span&gt;, {&lt;span style=&#34;color: #FF6600&#34;&gt;email&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;email&lt;/span&gt;},
            {&lt;span style=&#34;color: #FF6600&#34;&gt;choices&lt;/span&gt;, &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;fun&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;check_choices&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;, []},
            {&lt;span style=&#34;color: #FF6600&#34;&gt;remember_me&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;boolean&lt;/span&gt;, &lt;span style=&#34;color: #000080&#34;&gt;false&lt;/span&gt;}]),
    &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;save_choices&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Name&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Email&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;ChoicesList&lt;/span&gt;),
    &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;if&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;RememberMe&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;create_account&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Name&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Email&lt;/span&gt;); &lt;span style=&#34;color: #000080&#34;&gt;true&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;ok&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;end&lt;/span&gt;&lt;/span&gt;,
    {&lt;span style=&#34;color: #FF6600&#34;&gt;ok&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Req&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;State&lt;/span&gt;}&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;

&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;check_choices&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color: #FF0000&#34;&gt;&#34;blue&#34;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; {&lt;span style=&#34;color: #000080&#34;&gt;true&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;blue&lt;/span&gt;};
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;check_choices&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color: #FF0000&#34;&gt;&#34;red&#34;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; {&lt;span style=&#34;color: #000080&#34;&gt;true&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;red&lt;/span&gt;};
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;check_choices&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;_&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #000080&#34;&gt;false&lt;/span&gt;;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;(Don&amp;#8217;t look too closely at the structure yet.)&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;As you can see in the above snippet, it becomes really easy
to go from query string to values. You can also use the map
directly as it is guaranteed to only contain the keys you
specified, any extra key is not returned.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This would I believe be a huge step up as we can now
focus on writing applications instead of translating HTTP
calls. Cowboy can now take care of it.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And to conclude, this also solves our duplicate keys
dilemma, as they now automatically become a list of binaries,
and this list is then checked against constraints that
will fail if they were not expecting a list. And in the
example above, it even converts the values to atoms for
easier manipulation.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;As usual, feedback is more than welcome, and I apologize
for the rocky structure of this post as it contains all the
thoughts that went into this rather than just the conclusion.&lt;/p&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>January 2014 status</title>
      <link>https://ninenines.eu/articles/january-2014-status/</link>
      <pubDate>Tue, 07 Jan 2014 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/january-2014-status/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I will now be regularly writing posts about project status, plans
and hopes for the future.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Before that though, there&amp;#8217;s one important news to share.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Until a year ago all development was financed through consulting
and development services. This worked alright but too much time was
spent doing things that didn&amp;#8217;t benefit the open source projects.
And that didn&amp;#8217;t make me happy at all. Because I like being happy
I stopped that for the most part and spent the year figuring things
out, experimenting and discussing with people about it.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;What makes me happy is answering these &#34;what if&#34; questions.
Ranch and Cowboy are a direct product of that, as they originate
from the &#34;what if we could have a server running different protocols
on different ports but all part of the same application?&#34;; Erlang.mk
is a bit different: &#34;this works great for me, what if it could
become the standard solution for building Erlang applications?&#34;.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;When I successfully answer the question, this becomes a project
that may end up largely benefiting the Erlang community. I love
Erlang and I love enabling people to build awesome products based
on my projects. It&amp;#8217;s a lot more rewarding than activities like
consulting where you only help one company at a time. And it&amp;#8217;s
also a much better use of my time as this has a bigger impact on
the community.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The hard part is to figure out how to be able to spend 100%
of the time on projects that you basically give away for free,
and still be able to afford living.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The immediate solution was getting work sponsored by the
&lt;a href=&#34;http://www.leofs.org/&#34;&gt;LeoFS project&lt;/a&gt;. LeoFS is a great
distributed file storage that I can only recommend to anyone who
needs to store files or large pieces of data. The sponsorship
works pretty great, and spurred development of the SPDY code in
Cowboy amongst other things, plus a couple upcoming projects
done more recently and getting a final touch before release.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;It turns out sponsoring works great. So I&amp;#8217;m thinking of
expanding on it and hopefully get enough sponsoring for fulltime
open source development. So I figured out a few things that
can give incentive to companies willing to sponsor.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Sponsors can &lt;em&gt;request that a particular version of Cowboy
be maintained indefinitely&lt;/em&gt; (as long as they&amp;#8217;re sponsoring).
This means fixes will be backported. This doesn&amp;#8217;t include
features although I can take requests depending on feasability.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Sponsors can &lt;em&gt;have a direct, private line of communication&lt;/em&gt;,
useful when they need help debugging or optimizing their product.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Sponsors can &lt;em&gt;get their name associated with one of the
project&lt;/em&gt; and get a good standing in the community thanks
to this. They would be featured in the README of the project
which is viewed by hundreds of developers daily.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Sponsors can &lt;em&gt;be listed on this website&lt;/em&gt;. I will modify
the front page when we get a few more sponsors, they will be
featured below the carousel of projects.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Please &lt;a href=&#34;mailto:[email protected]&#34;&gt;contact us&lt;/a&gt; if
you are interested in sponsoring, and say how much you are willing
to sponsor. The goal here is only to have enough money to make a
living and attend a few conferences. There&amp;#8217;s an upper limit in the
amount needed per year, so the more sponsors there are the cheaper
it becomes to everyone.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The upper limit stems from the new legal entity that will replace
the current Nine Nines. This is mostly to lower the legal costs and
simplify the administrative stuff and allow me to dedicate all my
time on what&amp;#8217;s important. From your point of view it&amp;#8217;s business as
usual.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Now on to project statuses and future works.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
&lt;h2 id=&#34;_cowboy&#34;&gt;Cowboy&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Cowboy is getting ready for a 1.0 release. Once multipart support
is in, all that&amp;#8217;s left is finishing the guide, improving tests and
finishing moving code to the cowlib project. I hope everything will
be ready around the time R17B is released.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I already dream of some API breaking changes after 1.0, which
would essentially become 2.0 when they&amp;#8217;re done. An extensive survey
will be setup after the 1.0 release to get more information on what
people like and don&amp;#8217;t like about the API.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And of course, when clients start implementing HTTP/2.0 then we
will too.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
&lt;h2 id=&#34;_ranch&#34;&gt;Ranch&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Ranch is also getting close to 1.0. I am currently writing a
test suite for upgrades. After that I also would like to write
a chaos_monkey test suite and add a getting started chapter to the
guide.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Ranch is pretty solid otherwise, it&amp;#8217;s hard to foresee new
features at this point.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
&lt;h2 id=&#34;_erlang_mk&#34;&gt;Erlang.mk&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I didn&amp;#8217;t expect this project to become popular. Glad it did though.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Windows support is planned, but will require GNU Make 4.
Thankfully, it&amp;#8217;s available at least through cygwin. Make,
Git and Erlang will be the only required dependencies
because the rest of the external calls will be converted to
using Guile, a Scheme included since GNU Make 4. So it is
Guile that will download the needed files, magically fill
the list of modules in the &lt;em&gt;.app&lt;/em&gt; file and so on, allowing
us to provide a truly cross-platform solution without
losing on the performance we benefit from using Make.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Also note that it is possible to check whether Guile
is available so we will be able to fallback to the current
code for older systems.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I am also thinking about adding an extra column to the package
index, indicating the preferred tag or commit number to be used.
This would allow us to skip the individual &lt;code&gt;dep&lt;/code&gt; lines
entirely if the information in the package index is good enough.
And committing that file to your project would be the only thing
needed to lock the dependencies. Of course if a &lt;code&gt;dep&lt;/code&gt;
line is specified this would instead override the file.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
&lt;h2 id=&#34;_alien_shaman&#34;&gt;Alien Shaman&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This is the two-parts project requested by the LeoFS team.
This is essentially a &#34;distributed bigwig&#34;. I am hoping to
have a prototype up in a few days.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Alien is the part that allows writing and enabling probes
in your nodes. Probes send events which may get filtered before
being forwarded to their destination. The events may be sent
to a local process, a remote process, over UDP, TCP or SSL.
Events may also be received by a process called a relay, which
may be used to group or aggregate data before it is being sent
over the network, reducing the footprint overall.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Shaman is the UI for it. It will ultimately be able to display
any event as long as it&amp;#8217;s configured to do so. Events may be logs,
numeric values displayed on graphs updated in real time, lists of
items like processes and so on.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
&lt;h2 id=&#34;_feedback&#34;&gt;Feedback&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;That&amp;#8217;s it for today! There will be another status update once
Shaman is out. But for now I have to focus on it.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;As always, please send feedback on the projects, this post,
the sponsoring idea, anything really! Thanks.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Farwest got funded!</title>
      <link>https://ninenines.eu/articles/farwest-funded/</link>
      <pubDate>Thu, 27 Jun 2013 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/farwest-funded/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This was a triumph! I&amp;#8217;m making a note here: HUGE SUCCESS!!&lt;/p&gt;&lt;/div&gt;
&lt;iframe frameborder=&#34;0&#34; scrolling=&#34;no&#34; height=&#34;400px&#34; width&#34;236px&#34; seamless=&#34;seamless&#34; src=&#34;https://api.bountysource.com/user/fundraisers/83/embed&#34;&gt;&lt;/iframe&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;It&amp;#8217;s hard to overstate my satisfaction. Thanks to everyone who
made this possible.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;If you have backed this fundraiser, and haven&amp;#8217;t provided your
personal details yet, please do so quickly so that your rewards
can be sent!&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I am hoping that we will be able to make good use of all that
money. The details of the expenses will be published regularly
on the &lt;a href=&#34;https://github.com/extend/farwest/wiki/2013-Fundraiser&#34;&gt;2013 Fundraiser wiki page&lt;/a&gt;,
giving you full disclosure as to how your money is used.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;It will take a little time to get things started, we are in
summer after all! We will however act quickly to make the
prototype easy enough to use so that the paid UI work can
begin. This is also when user contributions will be welcome.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;You can see the &lt;a href=&#34;https://github.com/extend/farwest/wiki/Roadmap&#34;&gt;Roadmap&lt;/a&gt;
to get more information on the current plans. This document will
get updated as time goes on so check again later to see if you
can help!&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Look at me: still talking when there&amp;#8217;s open source to do!&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Thanks again for all your support. I really appreciate it.&lt;/p&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Build Erlang releases with Erlang.mk and Relx</title>
      <link>https://ninenines.eu/articles/erlang.mk-and-relx/</link>
      <pubDate>Tue, 28 May 2013 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/erlang.mk-and-relx/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Building OTP releases has always been a difficult task. Tools like
Reltool or Rebar have made this simpler, but
it&amp;#8217;s no panacea. This article will show you an alternative and
hopefully much simpler solution.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;There is two steps to building a release. First you need to build
the various OTP applications you want to include in the release. Once
done, you need to create the release itself, by including the Erlang
runtime system alongside the applications, a boot script to start the
node and all its applications, and some configuration files.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/extend/erlang.mk&#34;&gt;Erlang.mk&lt;/a&gt; solves
the first step. It is an include file for GNU Make. Just
including it in a Makefile is enough to allow building your project,
fetching and building dependencies, building documentation, performing
static analysis and more.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/erlware/relx&#34;&gt;Relx&lt;/a&gt; solves the second
step. It is a release creation tool, wrapped into a single executable
file. It doesn&amp;#8217;t require a configuration file. And if you do need one,
it will be a pretty small one.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Let&amp;#8217;s take a look at the smallest Erlang.mk powered
Makefile. There is only one thing required: defining the project
name.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Simply doing this allows you to build your application by typing
&lt;code&gt;make&lt;/code&gt;, running tests using &lt;code&gt;make tests&lt;/code&gt;, and
more. It will even compile your &lt;em&gt;.dtl&lt;/em&gt; files found in the
&lt;em&gt;templates/&lt;/em&gt; directory if you are using ErlyDTL!&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Let&amp;#8217;s now take a look at a simplified version of the Makefile for
this website. I only removed a few targets that were off-topic.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;You can see here how to define dependencies. First you list all
the dependency names, then you have one line per dependency, giving
the repository URL and the commit number, tag or branch you want.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Then you can see two targets defined, with &lt;code&gt;release&lt;/code&gt;
becoming the default target, because it was defined first. You can
override the default target &lt;code&gt;all&lt;/code&gt;, which builds the
application and its dependencies, this way.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And as you can see, the &lt;code&gt;release&lt;/code&gt; target uses
Relx to build a release into the &lt;em&gt;rel/ninenines/&lt;/em&gt;
directory. Let&amp;#8217;s take a look at the configuration file for this release.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;{&lt;span style=&#34;color: #FF6600&#34;&gt;release&lt;/span&gt;, {&lt;span style=&#34;color: #FF6600&#34;&gt;ninenines&lt;/span&gt;, &lt;span style=&#34;color: #FF0000&#34;&gt;&#34;1&#34;&lt;/span&gt;}, [&lt;span style=&#34;color: #FF6600&#34;&gt;ninenines&lt;/span&gt;]}&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;

{&lt;span style=&#34;color: #FF6600&#34;&gt;extended_start_script&lt;/span&gt;, &lt;span style=&#34;color: #000080&#34;&gt;true&lt;/span&gt;}&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;
{&lt;span style=&#34;color: #FF6600&#34;&gt;sys_config&lt;/span&gt;, &lt;span style=&#34;color: #FF0000&#34;&gt;&#34;rel/sys.config&#34;&lt;/span&gt;}&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;

{&lt;span style=&#34;color: #FF6600&#34;&gt;overlay&lt;/span&gt;, [
        {&lt;span style=&#34;color: #FF6600&#34;&gt;mkdir&lt;/span&gt;, &lt;span style=&#34;color: #FF0000&#34;&gt;&#34;log&#34;&lt;/span&gt;},
        {&lt;span style=&#34;color: #FF6600&#34;&gt;copy&lt;/span&gt;, &lt;span style=&#34;color: #FF0000&#34;&gt;&#34;rel/vm.args&#34;&lt;/span&gt;,
                &lt;span style=&#34;color: #FF0000&#34;&gt;&#34;releases/\{\{release_name\}\}-\{\{release_version\}\}/vm.args&#34;&lt;/span&gt;}
]}&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The first line defines a release named &lt;code&gt;ninenines&lt;/code&gt;, which
has a version number &lt;code&gt;&#34;1&#34;&lt;/code&gt; and includes one application, also
named &lt;code&gt;ninenines&lt;/code&gt;, although it doesn&amp;#8217;t have to.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;We then use the &lt;code&gt;extended_start_script&lt;/code&gt; option to tell
Relx that we would like to have a start script that allows
us to not only start the release, but do so with the node in the
background, or also to allow us to connect to a running node, and so on.
This start script has the same features as the one tools like
Rebar generates.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The rest of the file just makes sure our configuration files are
where we expect them. Relx will automatically take care
of your &lt;em&gt;sys.config&lt;/em&gt; file as long as you tell it where to
find it. The &lt;em&gt;vm.args&lt;/em&gt; file used by the extended start script
needs to be handled more explicitly by using an overlay however.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;How does Relx find what applications to include?
By looking at the application dependencies in the &lt;em&gt;.app&lt;/em&gt;
file of each OTP application. Make sure you put all dependencies in
there, &lt;em&gt;including&lt;/em&gt; library applications, and Relx
will find everything for you.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;For example, this release includes the following applications.
Only what&amp;#8217;s strictly required.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;
&lt;pre&gt;&lt;code&gt;compiler-4.9.1  crypto-2.3     kernel-2.16.1    ranch-0.8.3    syntax_tools-1.6.11
cowboy-0.8.5    erlydtl-0.7.0  ninenines-0.2.0  stdlib-1.19.1&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The &lt;em&gt;sys.config&lt;/em&gt; file is standard and
&lt;a href=&#34;http://www.erlang.org/doc/man/config.html&#34;&gt;well documented&lt;/a&gt;.
The &lt;em&gt;vm.args&lt;/em&gt; file is just an optionally multiline file
containing all the flags to pass to the Erlang VM, for example
&lt;code&gt;-name [email protected] -heart&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Building OTP releases has always been a difficult task. Until now.&lt;/p&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Xerl: intermediate module</title>
      <link>https://ninenines.eu/articles/xerl-0.5-intermediate-module/</link>
      <pubDate>Mon, 25 Mar 2013 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/xerl-0.5-intermediate-module/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Today we will start the work on the intermediate module
that will be used to run the code for the expressions found
in our file&amp;#8217;s body, replacing our interpreter.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This is what we want to have when all the work is done:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;
&lt;pre&gt;&lt;code&gt;xerl -&amp;gt; tokens -&amp;gt; AST -&amp;gt; intermediate -&amp;gt; cerl&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Today we will perform this work only on the atomic integer
expression however, so we will not build any module at the end.
We have a few more things to take care of before getting there.
This does mean that we completely break compilation of modules
though, so hopefully we can resolve that soon.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This intermediate representation is in the form of a module
which contains a single function: &lt;code&gt;run/0&lt;/code&gt;. This function
contains all the expressions from our Xerl source file.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;In the case of a Xerl source file only containing the integer
&lt;code&gt;42&lt;/code&gt;, we will obtain the following module ready to
be executed:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;-module&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$xerl_intermediate&#39;&lt;/span&gt;)&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;-export&lt;/span&gt;&lt;/span&gt;([&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;run&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;])&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;

&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;run&lt;/span&gt;&lt;/span&gt;() &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color: #993399&#34;&gt;42&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Running it will of course give us a result of &lt;code&gt;42&lt;/code&gt;,
the same we had when interpreting expressions.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The resulting Core Erlang code looks like this:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;module&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$xerl_intermediate&#39;&lt;/span&gt; [&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;run&#39;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;]
    &lt;span style=&#34;color: #FF6600&#34;&gt;attributes&lt;/span&gt; []
&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;run&#39;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;=&lt;/span&gt;
    &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;fun&lt;/span&gt;&lt;/span&gt; () &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color: #993399&#34;&gt;42&lt;/span&gt;
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The nice thing about doing it like this is that other than the
definition of the intermediate module and its &lt;code&gt;run/0&lt;/code&gt;
function, we can use the same code we are using for generating
the final Beam file. It may also be faster than interpreting
if you have complex modules.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Of course this here only works for the simplest cases, as you
cannot declare a module or a function inside another Erlang function.
We will need to wrap these into function calls to the Xerl compiler
that will take care of compiling them, making them available for
any subsequent expression. We will also need to pass the environment
to the &lt;code&gt;run&lt;/code&gt; function to keep track of all this.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This does mean that we will have different code for compiling
&lt;code&gt;fun&lt;/code&gt; and &lt;code&gt;mod&lt;/code&gt; expressions when creating
the intermediate module. But the many other expressions don&amp;#8217;t need
any special care.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Right now we&amp;#8217;ve used the &lt;code&gt;&#39;$xerl_intermediate&#39;&lt;/code&gt; atom
for the intermediate module name because we only have one, but we
will need to have a more random name later on when we&amp;#8217;ll implement
modules this way.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The attentive mind will know by now that when compiling a Xerl
file containing one module, we will need to compile two intermediate
modules: one for the file body, and one for the module&amp;#8217;s body. Worry
not though, if we only detect &lt;code&gt;mod&lt;/code&gt; instructions in the file
body, we can just skip this phase.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;While we&amp;#8217;re at it, we&amp;#8217;ll modify our code generator to handle lists
of expressions, which didn&amp;#8217;t actually work with integer literals
before.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;We&amp;#8217;re going to use Core Erlang sequences for running the many
expressions. Sequences work like &lt;code&gt;let&lt;/code&gt;, except no value
is actually bound. Perfect for our case, since we don&amp;#8217;t support
binding values at this time anyway.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Sequences have an argument and a body, both being Core Erlang
expressions. The simplest way to have many expressions is to use
a simple expression for the argument and a sequence for the rest
of the expressions. When we encounter the last expression in the
list, we do not create a sequence.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The result is this very simple function:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;comp_body&lt;/span&gt;&lt;/span&gt;([&lt;span style=&#34;color: #009900&#34;&gt;Expr&lt;/span&gt;]) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;expr&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Expr&lt;/span&gt;);
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;comp_body&lt;/span&gt;&lt;/span&gt;([&lt;span style=&#34;color: #009900&#34;&gt;Expr&lt;/span&gt;|&lt;span style=&#34;color: #009900&#34;&gt;Exprs&lt;/span&gt;]) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color: #009900&#34;&gt;Arg&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;expr&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Expr&lt;/span&gt;),
    &lt;span style=&#34;color: #009900&#34;&gt;Body&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;comp_body&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Exprs&lt;/span&gt;),
    &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;cerl:c_seq&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Arg&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Body&lt;/span&gt;)&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;In the case of our example above, a sequence will not be created,
we only have one expression. If we were to have &lt;code&gt;42, 43, 44&lt;/code&gt;
in our Xerl source file, we would have a result equivalent to the
following before optimization:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;-module&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$xerl_intermediate&#39;&lt;/span&gt;)&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;-export&lt;/span&gt;&lt;/span&gt;([&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;run&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;])&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;

&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;run&lt;/span&gt;&lt;/span&gt;() &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color: #993399&#34;&gt;42&lt;/span&gt;,
    &lt;span style=&#34;color: #993399&#34;&gt;43&lt;/span&gt;,
    &lt;span style=&#34;color: #993399&#34;&gt;44&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And the result is of course &lt;code&gt;44&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The resulting Core Erlang code looks like this:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;module&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$xerl_intermediate&#39;&lt;/span&gt; [&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;run&#39;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt;]
    &lt;span style=&#34;color: #FF6600&#34;&gt;attributes&lt;/span&gt; []
&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;run&#39;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;=&lt;/span&gt;
    &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;fun&lt;/span&gt;&lt;/span&gt; () &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color: #FF6600&#34;&gt;do&lt;/span&gt;  &lt;span style=&#34;color: #993399&#34;&gt;42&lt;/span&gt;
            &lt;span style=&#34;color: #FF6600&#34;&gt;do&lt;/span&gt;  &lt;span style=&#34;color: #993399&#34;&gt;43&lt;/span&gt;
                &lt;span style=&#34;color: #993399&#34;&gt;44&lt;/span&gt;
&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Feels very lisp-y, right? Yep.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;ulist&#34;&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
&lt;a href=&#34;https://github.com/extend/xerl/blob/0.5/&#34;&gt;View the source&lt;/a&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Xerl: expression separator</title>
      <link>https://ninenines.eu/articles/xerl-0.4-expression-separator/</link>
      <pubDate>Fri, 01 Mar 2013 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/xerl-0.4-expression-separator/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;As promised we are adding an expression separator this time.
This will be short and easy.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;In the tokenizer we only need to add a line recognizing the
comma as a valid token.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;, &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt; {&lt;span style=&#34;color: #FF6600&#34;&gt;token&lt;/span&gt;, {&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;,&#39;&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;TokenLine&lt;/span&gt;}}&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Then we need to change the following lines in the parser:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;exprs&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;expr&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$1&#39;&lt;/span&gt;]&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;
&lt;span style=&#34;color: #FF6600&#34;&gt;exprs&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;expr&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;exprs&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$1&#39;&lt;/span&gt; | &lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$2&#39;&lt;/span&gt;]&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And add a comma between the expressions on the second line:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;exprs&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;expr&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$1&#39;&lt;/span&gt;]&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;
&lt;span style=&#34;color: #FF6600&#34;&gt;exprs&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;expr&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;&#39;,&#39;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;exprs&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$1&#39;&lt;/span&gt; | &lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$3&#39;&lt;/span&gt;]&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;That takes care of everything except the optional trailing
comma at the end of our lists of expressions. We just need an
additional rule to take care of this.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;exprs&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;expr&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;&#39;,&#39;&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$1&#39;&lt;/span&gt;]&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;That&amp;#8217;s it.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Wondering why we don&amp;#8217;t have this optional trailing comma in
Erlang considering how easy it was and the number of people
complaining about it? Yeah, me too. But that&amp;#8217;s for someone else
to answer.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Another change I want to talk about is a simple modification
of the compiler code to use an &lt;code&gt;#env{}&lt;/code&gt; record for
tracking state instead of passing around individual variables.
This will be required later on when we make modules into proper
expressions so I thought it was a good idea to anticipate.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;ulist&#34;&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
&lt;a href=&#34;https://github.com/extend/xerl/blob/0.4/&#34;&gt;View the source&lt;/a&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Erlang Scalability</title>
      <link>https://ninenines.eu/articles/erlang-scalability/</link>
      <pubDate>Mon, 18 Feb 2013 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/erlang-scalability/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I would like to share some experience and theories on
Erlang scalability.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This will be in the form of a series of hints, which
may or may not be accompanied with explanations as to why
things are this way, or how they improve or reduce the scalability
of a system. I will try to do my best to avoid giving falsehoods,
even if that means a few things won&amp;#8217;t be explained.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
&lt;h2 id=&#34;_nifs&#34;&gt;NIFs&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;NIFs are considered harmful. I don&amp;#8217;t know any single NIF-based
library that I would recommend. That doesn&amp;#8217;t mean they should
all be avoided, just that if you&amp;#8217;re going to want your system to
scale, you probably shouldn&amp;#8217;t use a NIF.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;A common case for using NIFs is JSON processing. The problem
is that JSON is a highly inefficient data structure (similar
in inefficiency to XML, although perhaps not as bad). If you can
avoid using JSON, you probably should. MessagePack can replace
it in many situations.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Long-running NIFs will take over a scheduler and prevent Erlang
from efficiently handling many processes.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Short-running NIFs will still confuse the scheduler if they
take more than a few microseconds to run.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Threaded NIFs, or the use of the &lt;code&gt;enif_consume_timeslice&lt;/code&gt;
might help allievate this problem, but they&amp;#8217;re not a silver bullet.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And as you already know, a crashing NIF will take down your VM,
destroying any claims you may have at being scalable.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Never use a NIF because &#34;C is fast&#34;. This is only true in
single-threaded programs.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
&lt;h2 id=&#34;_bifs&#34;&gt;BIFs&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;BIFs can also be harmful. While they are generally better than
NIFs, they are not perfect and some of them might have harmful
effects on the scheduler.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;A great example of this is the &lt;code&gt;erlang:decode_packet/3&lt;/code&gt;
BIF, when used for HTTP request or response decoding. Avoiding
its use in &lt;em&gt;Cowboy&lt;/em&gt; allowed us to see a big increase in
the number of requests production systems were able to handle,
up to two times the original amount. Incidentally this is something
that is impossible to detect using synthetic benchmarks.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;BIFs that return immediately are perfectly fine though.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
&lt;h2 id=&#34;_binary_strings&#34;&gt;Binary strings&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Binary strings use less memory, which means you spend less time
allocating memory compared to list-based strings. They are also
more natural for strings manipulation because they are optimized
for appending (as opposed to prepending for lists).&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;If you can process a binary string using a single match context,
then the code will run incredibly fast. The effects will be much
increased if the code was compiled using HiPE, even if your Erlang
system isn&amp;#8217;t compiled natively.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Avoid using &lt;code&gt;binary:split&lt;/code&gt; or &lt;code&gt;binary:replace&lt;/code&gt;
if you can avoid it. They have a certain overhead due to supporting
many options that you probably don&amp;#8217;t need for most operations.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
&lt;h2 id=&#34;_buffering_and_streaming&#34;&gt;Buffering and streaming&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Use binaries. They are great for appending, and it&amp;#8217;s a direct copy
from what you receive from a stream (usually a socket or a file).&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Be careful to not indefinitely receive data, as you might end up
having a single binary taking up huge amounts of memory.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;If you stream from a socket and know how much data you expect,
then fetch that data in a single &lt;code&gt;recv&lt;/code&gt; call.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Similarly, if you can use a single &lt;code&gt;send&lt;/code&gt; call, then
you should do so, to avoid going back and forth unnecessarily between
your Erlang process and the Erlang port for your socket.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
&lt;h2 id=&#34;_list_and_binary_comprehensions&#34;&gt;List and binary comprehensions&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Prefer list comprehensions over &lt;code&gt;lists:map/2&lt;/code&gt;. The
compiler will be able to optimize your code greatly, for example
not creating the result if you don&amp;#8217;t need it. As time goes on,
more optimizations will be added to the compiler and you will
automatically benefit from them.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
&lt;h2 id=&#34;_gen_server_is_no_silver_bullet&#34;&gt;gen_server is no silver bullet&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;It&amp;#8217;s a bad idea to use &lt;code&gt;gen_server&lt;/code&gt; for everything.
For two reasons.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;There is an overhead everytime the &lt;code&gt;gen_server&lt;/code&gt; receives
a call, a cast or a simple message. It can be a problem if your
&lt;code&gt;gen_server&lt;/code&gt; is in a critical code path where speed
is all that matters. Do not hesitate to create other kinds of
processes where it makes sense. And depending on the kind of process,
you might want to consider making them special processes, which
would essentially behave the same as a &lt;code&gt;gen_server&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;A common mistake is to have a unique &lt;code&gt;gen_server&lt;/code&gt; to
handle queries from many processes. This generally becomes the
biggest bottleneck you&amp;#8217;ll want to fix. You should try to avoid
relying on a single process, using a pool if you can.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
&lt;h2 id=&#34;_supervisor_and_monitoring&#34;&gt;Supervisor and monitoring&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;A &lt;code&gt;supervisor&lt;/code&gt; is also a &lt;code&gt;gen_server&lt;/code&gt;,
so the previous points also apply to them.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Sometimes you&amp;#8217;re in a situation where you have supervised
processes but also want to monitor them in one or more other
processes, effectively duplicating the work. The supervisor
already knows when processes die, why not use this to our
advantage?&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;You can create a custom supervisor process that will perform
both the supervision and handle exit and other events, allowing
to avoid the combination of supervising and monitoring which
can prove harmful when many processes die at once, or when you
have many short lived processes.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;sect1&#34;&gt;
&lt;h2 id=&#34;_ets_for_lolspeed_tm&#34;&gt;ets for LOLSPEED(tm)&lt;/h2&gt;
&lt;div class=&#34;sectionbody&#34;&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;If you have data queried or modified by many processes, then
&lt;code&gt;ets&lt;/code&gt; public or protected tables will give you the
performance boost you require. Do not forget to set the
&lt;code&gt;read_concurrency&lt;/code&gt; or &lt;code&gt;write_concurrency&lt;/code&gt;
options though.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;You might also be thrilled to know that Erlang R16B will feature
a big performance improvement for accessing &lt;code&gt;ets&lt;/code&gt; tables
concurrently.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Xerl: atomic expressions</title>
      <link>https://ninenines.eu/articles/xerl-0.3-atomic-expressions/</link>
      <pubDate>Mon, 18 Feb 2013 00:00:00 +0100</pubDate>
      
      <guid>https://ninenines.eu/articles/xerl-0.3-atomic-expressions/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;We will be adding atomic integer expressions to our language.
These look as follow in Erlang:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;color: #993399&#34;&gt;42&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And the result of this expression is of course 42.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;We will be running this expression at compile time, since we
don&amp;#8217;t have the means to run code at runtime yet. This will of
course result in no module being compiled, but that&amp;#8217;s OK, it will
allow us to discuss a few important things we&amp;#8217;ll have to plan for
later on.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;First, we must of course accept integers in the tokenizer.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;{&lt;span style=&#34;color: #009900&#34;&gt;D&lt;/span&gt;}&lt;span style=&#34;color: #990000&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt; {&lt;span style=&#34;color: #FF6600&#34;&gt;token&lt;/span&gt;, {&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;integer&lt;/span&gt;&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;TokenLine&lt;/span&gt;, &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;list_to_integer&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;TokenChars&lt;/span&gt;)}}&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;We must then accept atomic integer expressions in the parser.
This is a simple change. The integer token is terminal so we need
to add it to the list of terminals, and then we only need to add
it as a possible expression.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;expr&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;integer&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$1&#39;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;A file containing only the number 42 (with no terminating dot)
will give the following result when parsing it. This is incidentally
the same result as when tokenizing.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;[{&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;integer&lt;/span&gt;&lt;/span&gt;,&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;,&lt;span style=&#34;color: #993399&#34;&gt;42&lt;/span&gt;}]&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;We must then evaluate it. We&amp;#8217;re going to interpret it for now.
Since the result of this expression is not stored in a variable,
we are going to simply print it on the screen and discard it.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;execute&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Filename&lt;/span&gt;, [{&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;integer&lt;/span&gt;&lt;/span&gt;, &lt;span style=&#34;color: #990000&#34;&gt;_&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Int&lt;/span&gt;}|&lt;span style=&#34;color: #009900&#34;&gt;Tail&lt;/span&gt;], &lt;span style=&#34;color: #009900&#34;&gt;Modules&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;io:format&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #FF0000&#34;&gt;&#34;integer ~p~n&#34;&lt;/span&gt;, [&lt;span style=&#34;color: #009900&#34;&gt;Int&lt;/span&gt;]),
    &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;execute&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Filename&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Tail&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Modules&lt;/span&gt;)&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;You might think by now that what we&amp;#8217;ve done so far this time
is useless. It brings up many interesting questions though.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;ulist&#34;&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
What happens if a file contains two integers?
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
Can we live without expression separators?
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
Do we need an interpreter for the compile step?
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This is what happens when we create a file that contains two
integers on two separate lines:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;[{&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;integer&lt;/span&gt;&lt;/span&gt;,&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;,&lt;span style=&#34;color: #993399&#34;&gt;42&lt;/span&gt;},{&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;integer&lt;/span&gt;&lt;/span&gt;,&lt;span style=&#34;color: #993399&#34;&gt;2&lt;/span&gt;,&lt;span style=&#34;color: #993399&#34;&gt;43&lt;/span&gt;}]&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And on the same lines:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;[{&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;integer&lt;/span&gt;&lt;/span&gt;,&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;,&lt;span style=&#34;color: #993399&#34;&gt;42&lt;/span&gt;},{&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;integer&lt;/span&gt;&lt;/span&gt;,&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;,&lt;span style=&#34;color: #993399&#34;&gt;43&lt;/span&gt;}]&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Does this mean we do not need separators between expressions?
Not quite. The &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;-&lt;/code&gt; operators are an
example of why we can&amp;#8217;t have nice things. They are ambiguous. They
have two different meanings: make an atomic integer positive or
negative, or perform an addition or a substraction between two
integers. Without a separator you won&amp;#8217;t be able to know if the
following snippet is one or two expressions:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;color: #993399&#34;&gt;42&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color: #993399&#34;&gt;12&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Can we use the line ending as an expression separator then?
Some languages make whitespace important, often the line
separator becomes the expression separator. I do not think this
is the best idea, it can lead to errors. For example the following
snippet would be two expressions:&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;listingblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;color: #009900&#34;&gt;Var&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;some_module:some_function&lt;/span&gt;&lt;/span&gt;() &lt;span style=&#34;color: #990000&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;some_module:other_function&lt;/span&gt;&lt;/span&gt;()
    &lt;span style=&#34;color: #990000&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;another_module:another_function&lt;/span&gt;&lt;/span&gt;()&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;It is not obvious what would happen unless you are a veteran
of the language, and so we will not go down that road. We will use
an expression separator just like in Erlang: the comma. We will
however allow a trailing comma to make copy pasting code easier,
even if this means some old academics guy will go nuts about it
later on. This trailing comma will be optional and simply discarded
by the parser when encountered. We will implement this next.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The question as to how we will handle running expressions
remains. We have two choices here: we can write an interpreter,
or we can compile the code and run it. Writing an interpreter
would require us to do twice the work, and we are lazy, so we will
not do that.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;You might already know that Erlang does not use the same code
for compiling and for evaluating commands in the shell. The main
reason for this is that in Erlang everything isn&amp;#8217;t an expression.
Indeed, the compiler compiles forms which contain expressions,
but you can&amp;#8217;t have forms in the shell.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;How are we going to compile the code that isn&amp;#8217;t part of a module
then? What do we need to run at compile-time, anyway? The body of
the file itself, of course. The body of module declarations. That&amp;#8217;s
about it.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;For the file itself, we can simply compile it as a big function
that will be executed. Then, everytime we encounter a module
declaration, we will run the compiler on its body, making its body
essentially a big function that will be executed. The same mechanism
will be applied when we encounter a module declaration at runtime.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;At runtime there&amp;#8217;s nothing else for us to do, the result of this
operation will load all the compiled modules. At compile time we
will also want to save them to a file. We&amp;#8217;ll see later how we can
do that.&lt;/p&gt;&lt;/div&gt;
&lt;div class=&#34;ulist&#34;&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
&lt;a href=&#34;https://github.com/extend/xerl/blob/0.3/&#34;&gt;View the source&lt;/a&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
</description>
    </item>
    
  </channel>
</rss>