summaryrefslogtreecommitdiffstats
path: root/2024/info/transducers-after.md
blob: f48b41d4b7212754cfb7ab0afd0f123f349f6bcf (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
<!-- Automatically generated by emacsconf-publish-after-page -->


<div class="transcript transcript-mainVideo"><a name="transducers-mainVideo-transcript"></a><h1>Transcript</h1>


<div class="transcript-heading">[[!template new="1" text="""Intro""" start="00:00:00.000" video="mainVideo-transducers" id="subtitle"]]</div>[[!template text="""Hi everyone, this is EmacsConf 2024. I'm Colin, and today""" start="00:00:00.000" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""I'll be talking about transducers.""" start="00:00:10.800" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""After introducing them, I'll share a bit of history about""" start="00:00:17.320" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""transducers and the problems that they solve, some basics""" start="00:00:21.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""about how we can use them, how they work, like how they're""" start="00:00:25.360" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""implemented, some demonstrations of how we can actually""" start="00:00:28.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""use them in the wild, and then some other discussions about""" start="00:00:32.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""issues that they have.""" start="00:00:36.960" video="mainVideo-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""What are transducers?""" start="00:00:41.520" video="mainVideo-transducers" id="subtitle"]]</div>[[!template text="""Okay, let's get right in. What are transducers?""" start="00:00:41.520" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Transducers are a way to do streaming iteration with a""" start="00:00:46.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""modern API.""" start="00:00:49.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Who are transducers for, and thereby, who is""" start="00:00:55.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""this talk for? Well, it's for people who want to do streamed""" start="00:01:00.360" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""data processing in Emacs. It's for people who perhaps""" start="00:01:05.600" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""aren't satisfied with the existing APIs, for example, the""" start="00:01:10.520" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""seq API, or some other common libraries that provide""" start="00:01:14.200" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""similar functionality. Maybe you're not a fan of the loop""" start="00:01:19.360" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""macro. Some people find it difficult to understand. Or""" start="00:01:23.720" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""maybe you've done a bunch of Clojure before, and you'd like""" start="00:01:29.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""more aspects of Clojure in your Emacs Lisp. Or maybe you're""" start="00:01:32.720" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""just interested in transducers in general, because the""" start="00:01:36.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""pattern has now been ported to multiple different Lisps.""" start="00:01:40.240" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""So I'm Colin. I'm fosskers on everything online, and I do""" start="00:01:48.840" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""mainly back-end programming work and a lot of open source""" start="00:01:55.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""software. I wrote Haskell for a long time, both as a hobbyist""" start="00:01:58.520" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""and professionally. Since the COVID years, I've been""" start="00:02:05.160" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""writing Rust, both open source and professionally. But now""" start="00:02:09.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""I find that in my spare time, I'm mostly writing Common Lisp.""" start="00:02:13.440" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Some things I learned from my years of Haskell was that a lot""" start="00:02:19.720" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""of programming is just altering the shape of data. You know,""" start="00:02:22.720" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""sometimes we work through our algorithm line by line. We're""" start="00:02:27.520" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""trying to just tell the computer exactly what to do. But if we""" start="00:02:31.360" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""step back, a lot of the time we're just getting in data of some""" start="00:02:36.240" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""shape, changing it, and then passing it along. A lot of""" start="00:02:39.640" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""these patterns are common, identified""" start="00:02:44.120" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""decades ago. For instance, we have some collection, and we""" start="00:02:49.280" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""want to transform every element of that collection and then""" start="00:02:53.640" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""pass it on. Or maybe we're trying to filter out bad elements""" start="00:02:57.000" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""in that collection. Or maybe we're looking for a specific""" start="00:03:01.200" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""element in that collection. Yes, you could write all that""" start="00:03:04.800" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""with for loops, but these kind of common patterns were""" start="00:03:07.760" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""identified and given names decades ago. So why not use them?""" start="00:03:11.840" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""They say that there are two major problems in computer""" start="00:03:18.560" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""science, one being cache validation and the other being""" start="00:03:21.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""naming things.""" start="00:03:25.760" video="mainVideo-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Common issues""" start="00:03:27.590" video="mainVideo-transducers" id="subtitle"]]</div>[[!template text="""I've identified five other problems that""" start="00:03:27.590" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""come up when we're trying to deal with collections of data,""" start="00:03:29.800" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""or big streams of data. One is that if we were trying to""" start="00:03:33.200" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""load a file all into memory all at once and process the whole""" start="00:03:40.600" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""thing, sometimes we can have memory problems. You've""" start="00:03:45.280" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""probably seen out-of-memory errors or such things.""" start="00:03:48.280" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""A second issue that comes up is that if we were looking at a""" start="00:03:55.000" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""giant for loop, in particular a nested for loop or such""" start="00:03:58.200" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""things, it can be hard to tell just by looking at the code what""" start="00:04:01.800" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""it's trying to do, what it intends. If we don't go character""" start="00:04:06.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""by character or line by line, it can be hard to understand it.""" start="00:04:11.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Furthermore, and this is particularly an issue with Emacs""" start="00:04:16.440" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Lisp, is that if one call, for instance, to seq-map, then""" start="00:04:20.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""piped into seq-filter, for instance, will have an""" start="00:04:26.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""intermediate allocation, the map will take the source""" start="00:04:29.320" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""container, allocate a new one, and then the filter will""" start="00:04:33.600" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""operate over the second one. This is wasteful.""" start="00:04:37.640" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Furthermore, it can often be difficult to abort a stream.""" start="00:04:40.320" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""For instance, if we were filtering through our collection,""" start="00:04:48.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""but we knew we only wanted to go halfway, for instance, for""" start="00:04:53.200" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""some reason, we have no way to stop it halfway through. We""" start="00:04:57.320" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""just have to process the whole thing, even if we know we don't""" start="00:05:01.760" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""need to. Another issue is that for languages that have""" start="00:05:05.480" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""traits, or in Haskell they're called type classes, if you""" start="00:05:11.920" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""are defining what it means to map over something, you often""" start="00:05:18.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""have to redefine that for every kind of container or thing""" start="00:05:22.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""that you're iterating over. Wouldn't it be nice if we could""" start="00:05:27.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""define things like map just once and then reuse them""" start="00:05:31.240" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""everywhere? Now, transducers solve all five of these,""" start="00:05:34.720" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""without the addition of new language features, and with""" start="00:05:39.840" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""little more than plain old function composition.""" start="00:05:44.040" video="mainVideo-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Transducers""" start="00:05:47.280" video="mainVideo-transducers" id="subtitle"]]</div>[[!template text="""If this is your first time hearing of transducers, yeah,""" start="00:05:47.280" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""no problem. They were originally invented in Clojure by""" start="00:05:53.120" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Rich Hickey, and this is a quote from him. He thinks""" start="00:05:57.440" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""transducers are a fundamental primitive that decouple""" start="00:06:01.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""critical logic from list or sequence processing, and if he""" start="00:06:05.440" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""had to do Clojure all over, he'd put them at the bottom, at the""" start="00:06:10.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""very bottom of all the fundamental primitives. Now, that's""" start="00:06:14.000" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Rich speaking quite highly of them. And I think he has a point""" start="00:06:19.280" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""here.""" start="00:06:24.600" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""They were invented originally in Clojure. In more""" start="00:06:25.160" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""recent years, they were brought over to Scheme""" start="00:06:32.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""via SRFI 171. That's where I found them""" start="00:06:34.773" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""when I was learning the Guile language.""" start="00:06:38.775" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""In the process of submitting a patch, I realized""" start="00:06:41.522" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""that there were other things to be improved. So I ported the""" start="00:06:43.920" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""pattern to Common Lisp, then Fennel, and then more""" start="00:06:48.200" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""recently, Emacs Lisp. The Common Lisp and Emacs Lisp APIs""" start="00:06:51.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""are identical. And the Fennel one is not identical, but""" start="00:06:56.640" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""fairly similar. Overall, everywhere you find""" start="00:07:01.200" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""transducers, they should basically be fairly uniform.""" start="00:07:05.800" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""When I originally made the Common Lisp variant first, I""" start="00:07:10.280" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""sampled the APIs from a number of different languages and""" start="00:07:15.760" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""came up with what I believed to be a representative sample of""" start="00:07:18.800" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""what most people would want out of such a library. I gave""" start="00:07:23.440" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""functions their common modern names. For instance, map""" start="00:07:27.960" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""is map and filter is filter and so on.""" start="00:07:32.440" video="mainVideo-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Using transducers""" start="00:07:35.280" video="mainVideo-transducers" id="subtitle"]]</div>[[!template text="""What does the usage of transducers look like? Well,""" start="00:07:35.280" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""these examples will all be the Emacs Lisp variant, but the""" start="00:07:42.600" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Common Lisp will look basically exactly the same, minus""" start="00:07:48.960" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""this little t- prefix.""" start="00:07:52.360" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Running transducers requires three things. It requires a""" start="00:07:54.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""source. This could be an obvious thing like a list or a""" start="00:08:00.920" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""vector, but it could be other things like a file, or in Emacs""" start="00:08:06.440" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""list in particular, a buffer.""" start="00:08:11.480" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""A reducer is a function. It's something like""" start="00:08:16.349" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""the + operator or the * operator,""" start="00:08:20.113" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""or certain constructors of various containers.""" start="00:08:22.640" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""It takes values and collates them into some final version.""" start="00:08:26.786" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Now, finally, we have what we're calling here""" start="00:08:32.126" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""a transducer chain. This could be one transducer function""" start="00:08:33.947" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""or it could be multiple composed together. These are the""" start="00:08:37.568" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""functions that actually take data and transform them""" start="00:08:43.480" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""somehow. For instance, this. We have a list of three""" start="00:08:47.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""elements. We want to reduce it into a vector. How we are""" start="00:08:55.280" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""going to transform the elements along the way: we are doing""" start="00:09:04.200" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""plus one to each of them. If this syntax is new to you, just""" start="00:09:07.520" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""know that this #' just means that this thing that""" start="00:09:13.360" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""comes after it is the name of the function. In Common Lisp and""" start="00:09:18.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Emacs Lisp, this is necessary, but for Clojure and Scheme,""" start="00:09:22.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""it is not. So we can see here that just this example is not much""" start="00:09:26.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""different than any other normal map call you might see made,""" start="00:09:32.720" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""but if nothing else, it's a handy way to convert a list to a""" start="00:09:36.120" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""vector or anything else. There are many, many reducers""" start="00:09:40.240" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""available and many different forms that we can""" start="00:09:45.000" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""collate the final value into.""" start="00:09:48.240" video="mainVideo-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""A more involved example with comp""" start="00:09:52.625" video="mainVideo-transducers" id="subtitle"]]</div>[[!template text="""Let's see a more involved example.""" start="00:09:52.625" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Okay, now we've got some more meat here.""" start="00:09:55.087" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Here we can see usage of the comp function""" start="00:09:58.050" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""and a custom source, ints.""" start="00:10:01.773" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Ints is an infinite generator of integer values. That's not""" start="00:10:05.256" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""like a list or a file. It will generate infinitely.""" start="00:10:11.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Comp is letting us compose multiple transducer functions""" start="00:10:14.784" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""together. Notice that this is the opposite order of what""" start="00:10:19.440" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""we'd usually be used to from a function like comp. The order""" start="00:10:23.760" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""here is top to bottom, basically, so that the map goes first,""" start="00:10:28.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""then the filter, and then the take. So effectively is what""" start="00:10:32.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""we're doing is taking all the integers that exist,""" start="00:10:37.840" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""positive, adding one to them, filtering out only the even""" start="00:10:40.920" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""ones, but then just taking 10. Cons here is a function that""" start="00:10:45.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""just produces the ending result as a list. So what happens""" start="00:10:50.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""here specifically is how we are avoiding intermediate""" start="00:10:57.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""allocations. First, the number 0 will come through.""" start="00:11:00.480" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""It will be pulled out of this source internally by transduce.""" start="00:11:04.239" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""It will make its way into the map. The map will add it. Then it""" start="00:11:07.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""will immediately go into this filter step. So it's not like""" start="00:11:10.920" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""all the maps occur, and then all the filters occur. We do""" start="00:11:15.800" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""everything for each element. So the 0 comes in, now it's 1.""" start="00:11:19.120" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""The filter would occur. Well, it's going to fail that""" start="00:11:24.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""because it's not even, so it will just bail there. Now we'll""" start="00:11:27.560" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""go to the next one. Now 1 will come, it will become 2, then""" start="00:11:31.120" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""it will be saved by this evenp call, and then the take will""" start="00:11:35.240" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""capture it, because we only want 10 values here. You can""" start="00:11:39.120" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""see 2, 4, 6, 8, and so on is the result that we""" start="00:11:42.600" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""expect. So let's play around a little bit.""" start="00:11:45.240" video="mainVideo-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""In Emacs""" start="00:11:49.333" video="mainVideo-transducers" id="subtitle"]]</div>[[!template text="""Let's jump into Emacs and see what we can do.""" start="00:11:49.333" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Alright, you should see my Emacs screen here.""" start="00:11:53.337" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""These are the actual notes for the actual""" start="00:11:58.501" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""presentation done in Org Mode. I'll boost that up in size for""" start="00:12:04.360" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""a little bit. That should be more than big enough for you.""" start="00:12:08.960" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Just by changing the reducer, we can change the result.""" start="00:12:12.640" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Okay, now it's a vector. Well, what else can we do to it? Well,""" start="00:12:17.720" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""let's just add up the results. Maybe we just want to count the""" start="00:12:21.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""results. Oh, indeed, there were 10. What if we want to find""" start="00:12:25.960" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""the average of the results? What if we want to find the median""" start="00:12:30.920" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""of the results? And so on. Here's some more interesting""" start="00:12:36.960" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""things that we could do. We could add different steps. So""" start="00:12:40.960" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""here we have all the integers. Let's add, hmm, okay, we'll""" start="00:12:45.840" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""keep that. We're going to add t-enumerate. What enumerate does""" start="00:12:51.240" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""is for each item that comes through, it is""" start="00:12:57.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""going to add a sort of index to it and make it a pair. In this""" start="00:13:00.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""case, it's going to be equal to what came in here. Well, we can""" start="00:13:06.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""change it. If we start this at 1, now it will be different.""" start="00:13:08.720" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""1 will be paired with 0, and then 2 would be paired""" start="00:13:12.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""with 1, and so on. We'll accept that the even call will change""" start="00:13:15.520" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""that a little bit. Why we're doing this is because we want""" start="00:13:19.560" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""to form a hash table. Let's move that down to 3, maybe""" start="00:13:24.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""we'll get a better result. What do we see? Okay, here now the""" start="00:13:27.280" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""result is a hash table. What are its values? Well, 0 seems""" start="00:13:31.440" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""to have... The key of 0 seems to be paired with 2, the key of""" start="00:13:37.360" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""1 seems to be paired with 4,""" start="00:13:40.480" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""and 2 seems to be paired with 6.""" start="00:13:42.910" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Maybe let's jazz that up even a little bit more.""" start="00:13:47.412" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""We're going to start from a string""" start="00:13:51.294" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""and we'll call it hello.""" start="00:13:52.974" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""That's not going to work anymore""" start="00:13:57.944" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""and neither is that, but what we could do is""" start="00:13:59.565" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""we could say t-map #'string.""" start="00:14:02.586" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""I believe we'll do that.""" start="00:14:05.499" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Let's see if that works. It did. So that's""" start="00:14:08.628" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""going to convert a character into a string.""" start="00:14:08.960" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Let's just go two""" start="00:14:13.590" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""just to make it a little easier. Now you can see that we've""" start="00:14:14.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""constructed a hash table here. The key of 0 is mapped to the""" start="00:14:18.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""string of h and 1 is mapped to e. Now, I really like having""" start="00:14:21.920" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""this reducer in particular.""" start="00:14:27.080" video="mainVideo-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Hash tables""" start="00:14:29.469" video="mainVideo-transducers" id="subtitle"]]</div>[[!template text="""Know that hash tables are""" start="00:14:29.469" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""also legal sources. I find that both in Emacs Lisp and in""" start="00:14:30.640" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Common Lisp, dealing with hash tables--like creating them""" start="00:14:34.200" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""and altering them--can be a bit of a pain. Having them""" start="00:14:37.120" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""immediately available like this with transducers is very""" start="00:14:41.600" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""handy, I find. We can work with something that wasn't a hash""" start="00:14:45.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""table. We can construct it in a way that makes it amenable to""" start="00:14:49.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""that, and then reduce it down into a hash table, and here you""" start="00:14:53.280" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""go. Very handy.""" start="00:14:56.200" video="mainVideo-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Clarity""" start="00:14:58.040" video="mainVideo-transducers" id="subtitle"]]</div>[[!template text="""One last point is that you can see very clearly what""" start="00:14:58.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""this is attempting to do, as opposed to, say, a for loop. It's""" start="00:15:06.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""very clear what that step is doing, and then you can see what""" start="00:15:10.480" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""that is doing, and you know that the result is going to be two.""" start="00:15:12.720" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Each line is kind of its own declarative step, and it should""" start="00:15:15.120" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""be clear, just by staring at this, basically what you're""" start="00:15:18.560" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""going to get out. This is one main difference from other""" start="00:15:22.160" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""languages that have things--say, for instance, Rust's""" start="00:15:25.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""iterator API--is the difference between the transducers""" start="00:15:29.600" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""and the reducers. If we go up here, for example, the""" start="00:15:35.440" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""difference between the transducers and the reducers and""" start="00:15:41.640" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""the sources is not explicitly laid out, whereas with""" start="00:15:44.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""transducers, it is. You have to be aware of how these things""" start="00:15:48.120" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""are different. I think that that helps clarity.""" start="00:15:53.120" video="mainVideo-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""How do transducers work?""" start="00:15:55.800" video="mainVideo-transducers" id="subtitle"]]</div>[[!template text="""Moving on. How do transducers work? Well,""" start="00:15:55.800" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""we want to go see the README.""" start="00:16:02.000" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""So, what we're going to do is""" start="00:16:09.858" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""we're going to go to here.""" start="00:16:11.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""You should still be able to see this.""" start="00:16:19.103" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""This is the CL example, actually.""" start="00:16:21.960" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Let's go to transducers.el.""" start="00:16:28.584" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Their APIs and READMEs are the same,""" start="00:16:32.280" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""but just for the sake of it, we will go see""" start="00:16:37.745" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""how this looks on the Emacs side,""" start="00:16:39.920" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""just so that nothing is a surprise.""" start="00:16:45.727" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""But recall that the APIs are essentially the same""" start="00:16:48.047" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""between the two. If you go to this section, writing your""" start="00:16:50.240" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""own primitives, you can read about how transducers are""" start="00:16:53.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""actually formed, whether or not you want to write them""" start="00:16:56.840" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""yourself or not. We can see here t-map. We accept the""" start="00:17:01.000" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""function that you want to operate with. Then you've got""" start="00:17:06.800" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""this extra little lambda here that's coming in, and it's""" start="00:17:10.240" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""receiving a thing that is named reducer. Now, while here""" start="00:17:13.320" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""we're calling it reducer, it's actually the chain of all the""" start="00:17:17.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""composed functions together. It's all those main""" start="00:17:20.440" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""transducer steps. Finally, it's the reducer all""" start="00:17:25.160" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""composed together with normal function composition.""" start="00:17:28.480" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""That will matter very soon. Now here's the actual meat.""" start="00:17:31.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""We can see the accumulative result that's coming in with the""" start="00:17:35.878" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""current element. Now we need to operate on this.""" start="00:17:40.520" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Were it normally mapped, we would see us""" start="00:17:45.740" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""applying the F to the input.""" start="00:17:47.841" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""But here, you can see us applying the F to the input and then""" start="00:17:49.920" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""continuing on. So us calling the rest of the composed chain""" start="00:17:53.520" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""here is the effect of, in the previous slide, moving to the""" start="00:17:58.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""next step. We could ignore this line for now.""" start="00:18:03.160" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""If you're curious, please read the README in detail.""" start="00:18:07.157" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Now, what about reducers?""" start="00:18:13.820" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""What do those look like? Well, let's just scroll""" start="00:18:15.580" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""down here. Recall that a reducer is a function that's""" start="00:18:18.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""consuming a stream, right? Zoom that up for you a little bit.""" start="00:18:22.440" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Now, in the case of count, recall that this is how it's""" start="00:18:26.960" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""working, how we saw a moment ago. So clearly this list of five""" start="00:18:33.920" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""elements only has five things in it. Well, a reducer by""" start="00:18:37.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""structure is a function of two, one, or zero arguments. So we""" start="00:18:42.200" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""can see here in the case of two, this is the normal iterative""" start="00:18:47.600" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""case. We don't care about the input for count, we just care""" start="00:18:50.640" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""about the current accumulated count that we're doing, and""" start="00:18:54.520" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""we add one to it, and that's it. This then goes back to""" start="00:18:58.560" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""the loop and the whole process starts again with the next""" start="00:19:02.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""element. In this kind of done case, this is used internal to""" start="00:19:06.360" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""that sort of the supervising function transduce. It's just""" start="00:19:10.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""confirming the final result. Sometimes some""" start="00:19:16.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""post-processing is necessary here, but in the case of""" start="00:19:19.640" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""count, as it is so simple, that is not necessary. And now""" start="00:19:21.840" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""here's the base case. This is also used within that""" start="00:19:26.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""supervising transduce function at the very top. Well, if""" start="00:19:29.360" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""you're counting, you have to start from somewhere, right?""" start="00:19:34.320" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""In this case, well, what you're starting with is zero.""" start="00:19:36.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""In the case of cons, you'd be starting with an empty list.""" start="00:19:37.350" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""In the case of vector, you'd be starting""" start="00:19:40.252" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""with an empty vector and so on.""" start="00:19:44.435" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Once again, if you are more curious, please take a look at""" start="00:19:54.000" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""the README.""" start="00:19:56.800" video="mainVideo-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Transducers in the wild - CSV""" start="00:20:00.520" video="mainVideo-transducers" id="subtitle"]]</div>[[!template text="""Okay, transducers in the wild. Well, let's go take a look at""" start="00:20:00.520" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""processing some CSV data.""" start="00:20:06.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""We're going to open up a new Emacs Lisp bracket here. So I have""" start="00:20:07.640" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""a file. And in this file, let's just go look at C-x b right""" start="00:20:21.320" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""there, you will see that we've got some bank transaction""" start="00:20:28.840" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""information. It's got these transactions from a whole""" start="00:20:34.840" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""bunch of different people into different accounts,""" start="00:20:37.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""whether it's money coming in, money going out, and then a""" start="00:20:40.200" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""basic description. How's your Latin? But for this little""" start="00:20:43.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""test, what we want to do is we want to find Bob's final bank""" start="00:20:47.840" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""balance. Let's get on to it. First of all, let's""" start="00:20:53.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""just confirm, let's do some basic stuff.""" start="00:20:59.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""with-current-buffer, find-file-noselect.""" start="00:21:04.445" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""What's the name of that file?""" start="00:21:10.845" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""This is pre-organized, so you""" start="00:21:15.543" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""will just see it right here.""" start="00:21:17.440" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""t-transduce and t-comp. We don't know what we're going to comp""" start="00:21:20.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""yet. Actually, I'll just pass to show you. And then we will""" start="00:21:27.000" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""see, let's just do a little t-count just to confirm. What's""" start="00:21:33.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""our source? Well, our source is a buffer, t-buffer-read.""" start="00:21:37.000" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""And note that because we're using with-current-buffer,""" start="00:21:45.113" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""if we go like this, if we go current-buffer, this will just work. So""" start="00:21:50.154" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""now let's... Well, that was odd. I should have done it like""" start="00:21:55.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""that. There we go. So now we should make that a little smaller""" start="00:21:59.920" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""so you can see what it is. Now if we hit RET, we should get the""" start="00:22:02.160" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""right result. Okay, so there are 50,001 lines in this file,""" start="00:22:04.800" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""but the one extra one is the name of the headers, right?""" start="00:22:09.560" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""We want to process this file in more detail. So how can we do""" start="00:22:13.517" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""that? Well, let's start by just automatically""" start="00:22:18.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""interpreting the results as CSV. If we do that, okay, well""" start="00:22:22.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""now we only have 50,000 entries as we expected, right?""" start="00:22:28.800" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Because it's going to pull out the header line. If we now say""" start="00:22:31.560" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""we want to just filter out, you know, We only want Bob, right?""" start="00:22:36.760" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""So if... gethash, it was in the row of name. Each line here is""" start="00:22:42.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""made into, at least by default, is made into a hash map. So if""" start="00:22:53.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""we go like this, we should see that. Okay, so 12,000 of these""" start="00:22:57.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""lines or thereabout belong to Bob.""" start="00:23:02.760" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Let's just move that over a little bit. Actually, I suppose we don't even""" start="00:23:05.640" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""need that anymore. I'll just keep that full size for you.""" start="00:23:13.840" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Okay, so all right, there's about 12,000 results for Bob of""" start="00:23:17.800" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""the 50,000. What's next? Well, we want to confirm,""" start="00:23:24.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""we want to pull out everything,""" start="00:23:32.480" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""all of the in and the out entries.""" start="00:23:40.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Thank you. So, string to number, because we know that""" start="00:23:43.080" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""everything came in as strings. Unfortunately, the from-csv""" start="00:23:56.280" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""doesn't try to be smart at all, it's just pulling everything""" start="00:24:01.240" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""in as string values. If you want actual things to be""" start="00:24:03.800" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""numbers or whatever, that is up to you to do the parsing""" start="00:24:09.480" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""yourself. Okay, so we have those two values now. We know""" start="00:24:13.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""that we saw from the data just a moment ago that you're only""" start="00:24:20.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""going to have a value in one column or the other. It's either""" start="00:24:23.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""going to be 0 in the empty one, or you're going to have some""" start="00:24:27.000" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""number in the other. So we know that we can just naively add""" start="00:24:29.120" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""them. If it was in, it would always be positive. So we'll just""" start="00:24:32.160" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""add that. But in the negative case, we want to just make it""" start="00:24:35.480" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""negative really briefly before we add them all together.""" start="00:24:41.520" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""let's now just prove to ourselves that we are sane here. What""" start="00:24:45.280" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""we're going to do is we're going to quickly go say take""" start="00:24:50.520" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""5 just to convince ourselves, and we'll go cons, and let's""" start="00:24:52.480" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""see if we get kind of results that make sense. Okay, these""" start="00:24:57.040" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""sort of make sense. It looks like you know Bob's got some big""" start="00:24:59.840" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""expenses here. If we take say 15, does it look any better?""" start="00:25:02.800" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Okay, looks like he had a payday. All right, good job Bob.""" start="00:25:07.680" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Let's get back in there. Now we only really care about""" start="00:25:10.320" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""adding the final result, right? So there we go. Add that all""" start="00:25:15.440" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""together and we'll see what we get in a moment. Okay, wow,""" start="00:25:20.120" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Bob's rich. Okay, so it looks like in his 12,000""" start="00:25:24.560" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""transaction, Bob has an overall net worth of $8.5 million.""" start="00:25:27.520" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Looking pretty good.""" start="00:25:32.280" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""So here's an example of how you can, particularly in Emacs""" start="00:25:34.440" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Lisp, how you can very easily just get a file, consider it the""" start="00:25:39.000" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""current buffer, and then just do whatever you want to it.""" start="00:25:42.960" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Note that there is sort of first-class support for both CSV""" start="00:25:45.880" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""and JSON, and then you have, and both of those bring in their""" start="00:25:50.360" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""values as hash maps, and then you're just free to do whatever""" start="00:25:54.360" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""you want and process them, potentially both writing them""" start="00:25:57.720" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""back out as CSV or JSON once again.""" start="00:26:00.440" video="mainVideo-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Issues and next steps""" start="00:26:03.240" video="mainVideo-transducers" id="subtitle"]]</div>[[!template text="""Some issues with transducers that can come up is""" start="00:26:03.240" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""that one, a zip operator is missing, but I'm working on it.""" start="00:26:10.720" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""Two is that performance, particularly in Emacs Lisp, isn't""" start="00:26:14.920" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""that great. It could be due to the sort of nested lambda calls""" start="00:26:19.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""that have to occur internally, but the common Lisp""" start="00:26:24.120" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""implementation is quite good. and there's yet no support""" start="00:26:27.760" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""for parallelism. You can imagine that a lot of those steps""" start="00:26:32.240" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""you could potentially perform in parallel depending on the""" start="00:26:35.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""platform, but research has not yet gotten that far. Okay,""" start="00:26:38.560" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""that's all. Thank you very much. If you have any questions,""" start="00:26:44.400" video="mainVideo-transducers" id="subtitle"]]
[[!template text="""please contact me.""" start="00:26:47.640" video="mainVideo-transducers" id="subtitle"]]

</div>

Captioner: sachac

<div class="transcript transcript-qanda"><a name="transducers-qanda-transcript"></a><h1>Q&A transcript (unedited)</h1>

[[!template text="""Hopefully the internet goes well. It's a nice Monday""" start="00:00:00.000" video="qanda-transducers" id="subtitle"]]
[[!template text="""morning here in Tokyo.""" start="00:00:07.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""Are we connected all right?""" start="00:00:32.000" video="qanda-transducers" id="subtitle"]]
[[!template text="""Okay, I seem to be struggling still with my audio. 1 2nd""" start="00:00:37.880" video="qanda-transducers" id="subtitle"]]
[[!template text="""calling. Yeah, you were muted for a moment there. Okay,""" start="00:00:40.880" video="qanda-transducers" id="subtitle"]]
[[!template text="""there we are. Okay. All right. Sorry about that. I got a mute""" start="00:00:44.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""out my, my back office chatter. That's kind of distracting""" start="00:00:49.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""me a little bit. All right. Sorry. I may have lost the plot a""" start="00:00:55.120" video="qanda-transducers" id="subtitle"]]
[[!template text="""little bit. I think I did. However, find the 1st question.""" start="00:00:58.080" video="qanda-transducers" id="subtitle"]]
[[!template text="""I got pretty distracted by conversation backstage. Yeah,""" start="00:01:04.920" video="qanda-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Q: When I tried comparing transducers.el to cl-lib and dash (benchmark-compiled), I got the following results""" start="00:01:09.920" video="qanda-transducers" id="subtitle"]]</div>[[!template text="""no problem. So the first question here, someone's asking,""" start="00:01:09.920" video="qanda-transducers" id="subtitle"]]
[[!template text="""when they first tried comparing transducers.el, the cl-lib""" start="00:01:15.880" video="qanda-transducers" id="subtitle"]]
[[!template text="""and Dash bookmark compiled, and they give some detailed""" start="00:01:22.280" video="qanda-transducers" id="subtitle"]]
[[!template text="""results we're sharing on the stream. Um, they expected""" start="00:01:27.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""transducers to be slower than CL loop, but faster than CL lib""" start="00:01:32.480" video="qanda-transducers" id="subtitle"]]
[[!template text="""or dash. However, this isn't the case, any idea why. And so""" start="00:01:36.680" video="qanda-transducers" id="subtitle"]]
[[!template text="""I'll, I'll come back into their data to show there's they're""" start="00:01:41.120" video="qanda-transducers" id="subtitle"]]
[[!template text="""showing, um, you know, there's not a lot of detail on the, on""" start="00:01:43.640" video="qanda-transducers" id="subtitle"]]
[[!template text="""the, on the use case here. We could certainly click through""" start="00:01:48.280" video="qanda-transducers" id="subtitle"]]
[[!template text="""it, do it.""" start="00:01:52.200" video="qanda-transducers" id="subtitle"]]
[[!template text="""Oh, I should've waited to zoom until I find my spot here.""" start="00:02:02.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""There we are.""" start="00:02:07.000" video="qanda-transducers" id="subtitle"]]
[[!template text="""All right, so there's our example.""" start="00:02:13.640" video="qanda-transducers" id="subtitle"]]
[[!template text="""Looks like we are doing a simple map and a sum.""" start="00:02:18.600" video="qanda-transducers" id="subtitle"]]
[[!template text="""Mm-hmm. Yeah, that's right. Yeah, question about""" start="00:02:23.760" video="qanda-transducers" id="subtitle"]]
[[!template text="""performance. So a case like this, a simple, I just want to rip""" start="00:02:29.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""through a collection of numbers and sum them all. That's a""" start="00:02:36.280" video="qanda-transducers" id="subtitle"]]
[[!template text="""case where basically loop is always going to win because""" start="00:02:40.280" video="qanda-transducers" id="subtitle"]]
[[!template text="""loop is optimized. This is true in both Emacs Lisp and in""" start="00:02:44.680" video="qanda-transducers" id="subtitle"]]
[[!template text="""Common Lisp. For a case like this where you're not really""" start="00:02:51.320" video="qanda-transducers" id="subtitle"]]
[[!template text="""doing two nested of chained calls, like you don't have many""" start="00:02:56.040" video="qanda-transducers" id="subtitle"]]
[[!template text="""sort of what I was compositional steps. If you're just""" start="00:03:02.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""ripping through a collection of numbers, loop is always""" start="00:03:05.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""going to win. Transducers kind of shines when you have to do""" start="00:03:10.000" video="qanda-transducers" id="subtitle"]]
[[!template text="""things that loop can't in terms of expressing yourself. So""" start="00:03:15.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""there are lots of different transducers that you can chain""" start="00:03:19.640" video="qanda-transducers" id="subtitle"]]
[[!template text="""together. And in that case, you're kind of prioritizing""" start="00:03:22.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""developer time and developer happiness because you're""" start="00:03:27.080" video="qanda-transducers" id="subtitle"]]
[[!template text="""able to yourself more clearly, whereas sometimes those""" start="00:03:33.040" video="qanda-transducers" id="subtitle"]]
[[!template text="""kind of algorithms can get very hairy if you're just using""" start="00:03:36.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""loop. Now that sounds like I'm moving the goalposts, and""" start="00:03:40.680" video="qanda-transducers" id="subtitle"]]
[[!template text="""there's really no excuse for these things not being as""" start="00:03:45.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""performant as possible. In this specific case, my guess is""" start="00:03:48.640" video="qanda-transducers" id="subtitle"]]
[[!template text="""that the transducers is slower because it has to do a whole""" start="00:03:54.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""bunch of like inner function calls in order to actually do""" start="00:03:57.760" video="qanda-transducers" id="subtitle"]]
[[!template text="""the adding and the collecting. So there's a lot of stuff that""" start="00:04:03.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""just the raw loop doesn't have to do, which transducers""" start="00:04:09.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""does. And so in this case, that's why it would be slower.""" start="00:04:12.120" video="qanda-transducers" id="subtitle"]]
[[!template text="""All right, makes sense.""" start="00:04:20.440" video="qanda-transducers" id="subtitle"]]
[[!template text="""Um... I cannot comment against Dash. And also a reminder""" start="00:04:29.080" video="qanda-transducers" id="subtitle"]]
[[!template text="""that transducers both in CL and in Emacs Lisp here doesn't""" start="00:04:36.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""attempt to do any, you know, fun, you know, inner rewriting""" start="00:04:40.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""or, you know, what's called an Haskell fusion. Like if you""" start="00:04:44.920" video="qanda-transducers" id="subtitle"]]
[[!template text="""have two different map steps, like in a row, it's not gonna""" start="00:04:48.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""see that and somehow fuse them internally. It's a fairly, in""" start="00:04:51.360" video="qanda-transducers" id="subtitle"]]
[[!template text="""that sense, the implementation is just as is.""" start="00:04:55.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""to make it you know as raw fast as possible. The idea being""" start="00:04:59.680" video="qanda-transducers" id="subtitle"]]
[[!template text="""that ergonomics is more important up front. Yeah, that's""" start="00:05:04.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""kind of a whole fascinating sub-panel, right? My theme this""" start="00:05:12.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""conference has been, oh, all these different things we""" start="00:05:17.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""should try to get sub-panels going for and use that. Maybe""" start="00:05:19.800" video="qanda-transducers" id="subtitle"]]
[[!template text="""fill in the dev track or even have a third track or whatever.""" start="00:05:24.040" video="qanda-transducers" id="subtitle"]]
[[!template text="""I'm not that concerned about the logistics of squeezing""" start="00:05:29.040" video="qanda-transducers" id="subtitle"]]
[[!template text="""into the schedule so much. But anyway, interesting, I mean,""" start="00:05:31.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""to say.""" start="00:05:38.520" video="qanda-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Q: Do you know of any theoretical texts on transducers?""" start="00:05:40.840" video="qanda-transducers" id="subtitle"]]</div>[[!template text="""Did we already speak to theoretical texts? No, right? No,""" start="00:05:40.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""let's continue. Okay, so another question from the group.""" start="00:05:47.800" video="qanda-transducers" id="subtitle"]]
[[!template text="""Do you know of any theoretical texts on transducers? My""" start="00:05:53.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""readme, particularly of the Common Lisp implementation,""" start="00:05:58.880" video="qanda-transducers" id="subtitle"]]
[[!template text="""is the theoretical text on transducers. Rich Hickey has""" start="00:06:01.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""some YouTube videos which also come close. I mean, he""" start="00:06:06.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""invented the things. But in terms of having a full""" start="00:06:10.440" video="qanda-transducers" id="subtitle"]]
[[!template text="""explanation of everything, it's my readme and it's also""" start="00:06:14.800" video="qanda-transducers" id="subtitle"]]
[[!template text="""the...""" start="00:06:21.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""The info manual of Guile Scheme, their documentation on""" start="00:06:23.320" video="qanda-transducers" id="subtitle"]]
[[!template text="""Surfy 171 is what I used to learn transducers and to""" start="00:06:28.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""re-implement them in other LISPs. So if you just want like a""" start="00:06:34.200" video="qanda-transducers" id="subtitle"]]
[[!template text="""document explaining them, MyReadMe is actually the""" start="00:06:38.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""clearest that I've found. Awesome. Okay, next question.""" start="00:06:41.640" video="qanda-transducers" id="subtitle"]]
[[!template text="""And I'm sorry, you gave a name, you referred to somebody's""" start="00:06:46.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""videos. Rich Hickey, the inventor of Clojure. Rich Hickey,""" start="00:06:50.120" video="qanda-transducers" id="subtitle"]]
[[!template text="""thank you. Hope I got the spelling right, and maybe somebody""" start="00:06:55.440" video="qanda-transducers" id="subtitle"]]
[[!template text="""can catch that and fix it. If not, I'll reach on. Thank you.""" start="00:07:00.400" video="qanda-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Q: Did you think about [compiler features, macros] viz your cl, fennel, elisp, porting of your transducers?""" start="00:07:04.720" video="qanda-transducers" id="subtitle"]]</div>[[!template text="""Reach on to the next question. Waters (Lazy Series in""" start="00:07:04.720" video="qanda-transducers" id="subtitle"]]
[[!template text="""Lisp, late 70s) said this should have been done as an""" start="00:07:08.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""additional compiler feature in compilers, but if not, must""" start="00:07:12.800" video="qanda-transducers" id="subtitle"]]
[[!template text="""be a macro package. Do you think about that vis your CL,""" start="00:07:16.800" video="qanda-transducers" id="subtitle"]]
[[!template text="""Fennel, Elisp, porting of transducers? I think that""" start="00:07:21.440" video="qanda-transducers" id="subtitle"]]
[[!template text="""there's definitely""" start="00:07:27.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""some Galaxy Brain Lisp author out there is probably smart""" start="00:07:28.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""enough to turn a bunch of this stuff into macros. I believe""" start="00:07:36.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""that's how the common Lisp library series works. It sees""" start="00:07:40.600" video="qanda-transducers" id="subtitle"]]
[[!template text="""that you were calling map or whatever, and it actually knows""" start="00:07:47.120" video="qanda-transducers" id="subtitle"]]
[[!template text="""that that's a special macro key. in order to be fast. I did not""" start="00:07:52.080" video="qanda-transducers" id="subtitle"]]
[[!template text="""do that. The implementation as I have it is very simple and""" start="00:07:56.640" video="qanda-transducers" id="subtitle"]]
[[!template text="""simplicity shouldn't be underestimated.""" start="00:08:01.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""I love it. What a nice succinct answer. Even I can manage to""" start="00:08:05.760" video="qanda-transducers" id="subtitle"]]
[[!template text="""type that out as I scroll us to the next question.""" start="00:08:13.560" video="qanda-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Q: Does t-buffer-read provide a lazy stream that\'s linewise, or charwise, or do something else entirely?""" start="00:08:16.579" video="qanda-transducers" id="subtitle"]]</div>[[!template text="""So, does t-buffer-read provide a lazy stream""" start="00:08:16.579" video="qanda-transducers" id="subtitle"]]
[[!template text="""that's line-wise or character-wise or do something else""" start="00:08:24.080" video="qanda-transducers" id="subtitle"]]
[[!template text="""entirely?""" start="00:08:28.360" video="qanda-transducers" id="subtitle"]]
[[!template text="""Okay, there are two functions. I showed""" start="00:08:29.019" video="qanda-transducers" id="subtitle"]]
[[!template text="""t-buffer-read. There's also one called t-file-read,""" start="00:08:31.588" video="qanda-transducers" id="subtitle"]]
[[!template text="""which does that. You actually have the buffer open,""" start="00:08:35.074" video="qanda-transducers" id="subtitle"]]
[[!template text="""it's much more clever.""" start="00:08:38.683" video="qanda-transducers" id="subtitle"]]
[[!template text="""t-buffer-read, I believe, is simpler. As long as you have an""" start="00:08:40.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""Emacs list, what is called the current buffer active. I'm""" start="00:08:46.000" video="qanda-transducers" id="subtitle"]]
[[!template text="""fairly sure you're able to just call next-line on it. I don't""" start="00:08:52.080" video="qanda-transducers" id="subtitle"]]
[[!template text="""believe that I'm doing anything fancy there, looking for""" start="00:08:56.680" video="qanda-transducers" id="subtitle"]]
[[!template text="""line ends. I believe I'm just grabbing the next line and then""" start="00:08:59.480" video="qanda-transducers" id="subtitle"]]
[[!template text="""processing that line-wise. Very good.""" start="00:09:04.000" video="qanda-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Q: Can the Elisp library be combined with the stream.el API or seq in general?""" start="00:09:09.424" video="qanda-transducers" id="subtitle"]]</div>[[!template text="""Can the Elisp library be combined with the stream.el API""" start="00:09:09.424" video="qanda-transducers" id="subtitle"]]
[[!template text="""or seq in general? I would say that these libraries""" start="00:09:17.304" video="qanda-transducers" id="subtitle"]]
[[!template text="""are completely orthogonal. You saw that everything""" start="00:09:22.831" video="qanda-transducers" id="subtitle"]]
[[!template text="""was prefixed by t-.""" start="00:09:27.597" video="qanda-transducers" id="subtitle"]]
[[!template text="""Basically, transducer is its own zone. However, one thing""" start="00:09:29.280" video="qanda-transducers" id="subtitle"]]
[[!template text="""that I do in the common lisp, which is theoretically""" start="00:09:36.880" video="qanda-transducers" id="subtitle"]]
[[!template text="""possible for the Emacs Lisp as well, is kind of like little""" start="00:09:40.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""shim libraries. So I provide, at least for Common Lisp, for a""" start="00:09:44.360" video="qanda-transducers" id="subtitle"]]
[[!template text="""number of, you know, popular sort of third-party""" start="00:09:48.920" video="qanda-transducers" id="subtitle"]]
[[!template text="""collection types, I provide an ability to use them as""" start="00:09:51.800" video="qanda-transducers" id="subtitle"]]
[[!template text="""sources. Maybe that's what you mean. Like""" start="00:09:55.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""the built-in containers for Emacs Lisp are already""" start="00:09:59.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""supported. So, you know, a vector hash table and so on.""" start="00:10:04.440" video="qanda-transducers" id="subtitle"]]
[[!template text="""make sense so i think what i heard there is yeah go ahead""" start="00:10:06.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""please sorry in terms of mixing like you know like for""" start="00:10:13.720" video="qanda-transducers" id="subtitle"]]
[[!template text="""instance you know like seek dash map used in transducers""" start="00:10:17.880" video="qanda-transducers" id="subtitle"]]
[[!template text="""we'll put it that way""" start="00:10:22.600" video="qanda-transducers" id="subtitle"]]
[[!template text="""i was just gonna say i think it um it it sounds like you're""" start="00:10:28.120" video="qanda-transducers" id="subtitle"]]
[[!template text="""saying Yeah, probably they are actually. We don't know yet""" start="00:10:31.880" video="qanda-transducers" id="subtitle"]]
[[!template text="""about any places where they don't play nicely together. So""" start="00:10:37.200" video="qanda-transducers" id="subtitle"]]
[[!template text="""quite possibly so. We can use sequence and transducers""" start="00:10:41.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""together, for example. As a source potentially, yeah. It's""" start="00:10:45.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""very easy because that just uses def generic. As long as you""" start="00:10:49.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""have a new, like if you have a new collection type, as long as""" start="00:10:54.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""you implement a def method for it somewhere, it'll just""" start="00:10:57.720" video="qanda-transducers" id="subtitle"]]
[[!template text="""magically work with this library. That's the magic of...""" start="00:11:01.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""Yeah, as an Emacs user enjoying, you know, sort of the""" start="00:11:12.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""renaissance of new features it's had, or sorry, Emacs ERC""" start="00:11:18.440" video="qanda-transducers" id="subtitle"]]
[[!template text="""user for chat. I've seen a lot of awesome stuff get done in the""" start="00:11:21.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""last couple of years with generic set. JP never was working""" start="00:11:27.800" video="qanda-transducers" id="subtitle"]]
[[!template text="""on that. And like, that's just making me my eyes pop and go,""" start="00:11:32.120" video="qanda-transducers" id="subtitle"]]
[[!template text="""wow, that does make a whole lot of things simpler, doesn't""" start="00:11:36.680" video="qanda-transducers" id="subtitle"]]
[[!template text="""it? I think we're a lot of us running into generics and how""" start="00:11:39.280" video="qanda-transducers" id="subtitle"]]
[[!template text="""that solves problems in Emacs.""" start="00:11:44.280" video="qanda-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Q: How does one debug a t-comp expression? Can you single step and see intermediate results of the different statements you declare?""" start="00:11:47.543" video="qanda-transducers" id="subtitle"]]</div>[[!template text="""How does one debug a t-comp""" start="00:11:47.543" video="qanda-transducers" id="subtitle"]]
[[!template text="""expression? Can you talk in terms of single step,""" start="00:11:50.280" video="qanda-transducers" id="subtitle"]]
[[!template text="""step-by-step, intermediate results of the different""" start="00:11:55.120" video="qanda-transducers" id="subtitle"]]
[[!template text="""statements you declare? Yes. So in Common Lisp, this is""" start="00:11:58.480" video="qanda-transducers" id="subtitle"]]
[[!template text="""and sly stickers and things like that. In Emacs Lisp, it's a""" start="00:12:08.760" video="qanda-transducers" id="subtitle"]]
[[!template text="""little bit, shall we say, more difficult. For step""" start="00:12:12.920" video="qanda-transducers" id="subtitle"]]
[[!template text="""debugging,""" start="00:12:19.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""so what comp does is comp internally, it should be a macro,""" start="00:12:20.480" video="qanda-transducers" id="subtitle"]]
[[!template text="""but currently it's not, although there's work to improve""" start="00:12:25.680" video="qanda-transducers" id="subtitle"]]
[[!template text="""that. It's doing an internal reduce and it's turning into""" start="00:12:28.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""one giant kind of composed lambda inside. So I don't know if""" start="00:12:33.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""step debugging would work there. However, we do have one""" start="00:12:37.480" video="qanda-transducers" id="subtitle"]]
[[!template text="""function called log, which lets you inspect intermediate""" start="00:12:43.000" video="qanda-transducers" id="subtitle"]]
[[!template text="""results. So you could technically use that to inject""" start="00:12:47.440" video="qanda-transducers" id="subtitle"]]
[[!template text="""yourself somewhere into the transduction chain and, you""" start="00:12:50.760" video="qanda-transducers" id="subtitle"]]
[[!template text="""know, halt or, you know, inspect the current value, et""" start="00:12:54.280" video="qanda-transducers" id="subtitle"]]
[[!template text="""cetera. So you get a bunch of questions lined up. I think""" start="00:12:57.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""we're coming up, uh, within our last five minutes, uh,""" start="00:13:01.120" video="qanda-transducers" id="subtitle"]]
[[!template text="""before some declared, uh, reset time that we have""" start="00:13:04.200" video="qanda-transducers" id="subtitle"]]
[[!template text="""internally to just roll our closing credits, so to speak.""" start="00:13:07.920" video="qanda-transducers" id="subtitle"]]
[[!template text="""Um, not that I would want to cut the question and answer""" start="00:13:11.920" video="qanda-transducers" id="subtitle"]]
[[!template text="""short, but I might have to step away personally. But, um, as""" start="00:13:14.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""we discussed before, you can just kind of run the QA, however""" start="00:13:18.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""you want here. Um, or, or take questions offline if you'd""" start="00:13:21.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""like to answer them off the pad. And I just want to say one more""" start="00:13:24.880" video="qanda-transducers" id="subtitle"]]
[[!template text="""time. Kitt said it managed later. Thanks again for your talk""" start="00:13:28.000" video="qanda-transducers" id="subtitle"]]
[[!template text="""for dedicating the time to this live QA. And I think we can see""" start="00:13:30.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""by the many questions that are here. So I'll try to kind of""" start="00:13:35.760" video="qanda-transducers" id="subtitle"]]
[[!template text="""flip us through as many of them as I can with our last couple of""" start="00:13:40.280" video="qanda-transducers" id="subtitle"]]
[[!template text="""minutes, if that sounds good. Alternately, this might be a""" start="00:13:42.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""good time if you have kind of wrap it up, final thoughts, as""" start="00:13:48.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""Leo Sopanda saying. By all means, have at. Sure, thanks a""" start="00:13:52.080" video="qanda-transducers" id="subtitle"]]
[[!template text="""lot. I'd say that if you are still curious, check out the""" start="00:13:58.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""read-me's because those have a lot of information,""" start="00:14:01.640" video="qanda-transducers" id="subtitle"]]
[[!template text="""including a full description of the API and everything""" start="00:14:05.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""that's available.""" start="00:14:09.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""Otherwise, just give them a shot. Using these things is the""" start="00:14:10.720" video="qanda-transducers" id="subtitle"]]
[[!template text="""best way to learn them, of course. I use them everywhere,""" start="00:14:16.600" video="qanda-transducers" id="subtitle"]]
[[!template text="""basically, all across my Emacs list and all across my common""" start="00:14:21.640" video="qanda-transducers" id="subtitle"]]
[[!template text="""list now. They get a lot of mileage. All right. You're""" start="00:14:24.720" video="qanda-transducers" id="subtitle"]]
[[!template text="""speaking our language now. As Emacs users, all our ears poke""" start="00:14:29.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""up when you say, I'm getting a lot of mileage. I'm using it""" start="00:14:33.640" video="qanda-transducers" id="subtitle"]]
[[!template text="""across everything. Every Emacs user has a story that""" start="00:14:36.040" video="qanda-transducers" id="subtitle"]]
[[!template text="""harmonizes with that, I think.""" start="00:14:39.880" video="qanda-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Q: Is there a path for transducers to enable elisp processing of otherwise overly large datasets as if just normal Emacs \"buffers\" (i.e. just pulling one thing at a time so essentially stream-like under the hood but buffer-like in interface), with none of the usual perf issues with a traditional buffer structure?""" start="00:14:42.495" video="qanda-transducers" id="subtitle"]]</div>[[!template text="""So our next question, is""" start="00:14:42.495" video="qanda-transducers" id="subtitle"]]
[[!template text="""there a path for transducers to enable Elisp processing or""" start="00:14:44.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""otherwise overly large data sets as if just normal Emacs""" start="00:14:48.600" video="qanda-transducers" id="subtitle"]]
[[!template text="""buffers, i.e. just pulling one thing at a time. So""" start="00:14:54.000" video="qanda-transducers" id="subtitle"]]
[[!template text="""essentially stream like under the hood, but buffer like an""" start="00:14:56.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""interface. I think that makes sense to me. with none of the""" start="00:15:00.720" video="qanda-transducers" id="subtitle"]]
[[!template text="""usual performance issues, like as if, you know, the history""" start="00:15:03.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""with long files is what that brings to mind, I guess. Yes, so""" start="00:15:07.800" video="qanda-transducers" id="subtitle"]]
[[!template text="""as you saw before, the withBufferRead sort of stream""" start="00:15:11.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""function does have to have the actual buffer in memory, and""" start="00:15:15.800" video="qanda-transducers" id="subtitle"]]
[[!template text="""then you can go really fast. But there's another one with""" start="00:15:19.880" video="qanda-transducers" id="subtitle"]]
[[!template text="""file read. Now, again, I haven't tried to optimize that yet.""" start="00:15:22.680" video="qanda-transducers" id="subtitle"]]
[[!template text="""But in theory, it is able to read right from the underlying""" start="00:15:26.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""file without having to open it as a buffer first.""" start="00:15:30.120" video="qanda-transducers" id="subtitle"]]
[[!template text="""Awesome. Ari, the performance issues mentioned, and that""" start="00:15:32.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""popped up recently in the list and forums, to what extent""" start="00:15:39.200" video="qanda-transducers" id="subtitle"]]
[[!template text="""does tail call optimization and other mechanisms like""" start="00:15:43.480" video="qanda-transducers" id="subtitle"]]
[[!template text="""inlining, garbage collection friendliness, and so on,""" start="00:15:46.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""could these alleviate issues, enable their use at little to""" start="00:15:50.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""no extra costs? I feel like we're leading the witness here,""" start="00:15:55.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""but I'm sure you see where we're going. Yeah, no problem. So""" start="00:15:58.440" video="qanda-transducers" id="subtitle"]]
[[!template text="""in terms of tail optimization, that's already happening""" start="00:16:01.280" video="qanda-transducers" id="subtitle"]]
[[!template text="""because the internal loop mechanism is using CL labels. And""" start="00:16:03.800" video="qanda-transducers" id="subtitle"]]
[[!template text="""in Emacs Lisp, CL labels is just a macro that is like""" start="00:16:09.200" video="qanda-transducers" id="subtitle"]]
[[!template text="""extremely tail recursive. So that's very, very fast. It's""" start="00:16:12.200" video="qanda-transducers" id="subtitle"]]
[[!template text="""not tail recursive, but it's using like goto. So it's""" start="00:16:16.080" video="qanda-transducers" id="subtitle"]]
[[!template text="""extremely, extremely fast, like the raw looping of it. So,""" start="00:16:19.040" video="qanda-transducers" id="subtitle"]]
[[!template text="""okay, well then where does the slowness come from? It's""" start="00:16:22.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""probably coming from those lambdas and it's probably""" start="00:16:24.360" video="qanda-transducers" id="subtitle"]]
[[!template text="""coming from, uh, like extra consing, extra allocation""" start="00:16:26.440" video="qanda-transducers" id="subtitle"]]
[[!template text="""somewhere, which is, um, sort of what you were, what you're""" start="00:16:32.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""referring to with the GC friendliness. So perhaps there's""" start="00:16:36.000" video="qanda-transducers" id="subtitle"]]
[[!template text="""some, um, um, yeah, some, like some fusion that I can do to""" start="00:16:38.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""speed it up. Yeah, that just sounds fascinating endlessly.""" start="00:16:45.200" video="qanda-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Q: Is there an option to read a csv/json and produce an alist or plist instead of a hash table for an entry?""" start="00:16:51.200" video="qanda-transducers" id="subtitle"]]</div>[[!template text="""Are there options to like read from a CSV, JSON, produce an""" start="00:16:51.200" video="qanda-transducers" id="subtitle"]]
[[!template text="""alist or plist instead of hash table? Absolutely.""" start="00:16:55.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""Yes, I need to double check that, but we can read both CSV and""" start="00:17:01.680" video="qanda-transducers" id="subtitle"]]
[[!template text="""JSON, and you should be able to just turn on the plist option.""" start="00:17:06.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""I will double check, but there's fairly free conversion""" start="00:17:10.360" video="qanda-transducers" id="subtitle"]]
[[!template text="""between those three types because hash table is not always""" start="00:17:14.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""what you want. And actually, I suspect that slowness that we""" start="00:17:18.040" video="qanda-transducers" id="subtitle"]]
[[!template text="""saw in the demo before was because it was allocating hash""" start="00:17:22.040" video="qanda-transducers" id="subtitle"]]
[[!template text="""tables for every, like, all of the 50,000 lines. And had it""" start="00:17:24.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""been a plist, it would have been faster. Interesting, so""" start="00:17:29.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""maybe there's opportunities even if you end up with hash""" start="00:17:32.600" video="qanda-transducers" id="subtitle"]]
[[!template text="""lists, but then they're shared strategically and you pay""" start="00:17:35.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""the cost of a little extra layer in there that buckets them""" start="00:17:38.800" video="qanda-transducers" id="subtitle"]]
[[!template text="""together the way that we might group files by the first four""" start="00:17:42.040" video="qanda-transducers" id="subtitle"]]
[[!template text="""characters in the file name once we've got a million files.""" start="00:17:46.440" video="qanda-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Q: Is the common lisp version ready for 'production' use? Is it complete enough and the API stable enough?""" start="00:17:50.520" video="qanda-transducers" id="subtitle"]]</div>[[!template text="""Anyway, is the Common Lisp version ready for production""" start="00:17:50.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""use? Do you want to comment on API stability? I use it all the""" start="00:17:54.480" video="qanda-transducers" id="subtitle"]]
[[!template text="""time. I'm writing a game in Common Lisp right now, and I'm""" start="00:17:59.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""using transducers everywhere in there, and it doesn't even""" start="00:18:04.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""make a dent in the frame rate, and I'm using them""" start="00:18:08.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""extensively. Okay, well, I'll just read from chat. Thanks""" start="00:18:11.120" video="qanda-transducers" id="subtitle"]]
[[!template text="""so much for the answers.""" start="00:18:15.360" video="qanda-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Q: Do we need a pre-written \"t-\" version for every already existing reducing function like + or is there a function to construct them from already defined reducer 2-arg functions?""" start="00:18:17.477" video="qanda-transducers" id="subtitle"]]</div>[[!template text="""Do we need a pre-written or t-minus""" start="00:18:17.477" video="qanda-transducers" id="subtitle"]]
[[!template text="""version for every already existing reducing function,""" start="00:18:20.440" video="qanda-transducers" id="subtitle"]]
[[!template text="""plus, as an example? Or is there a function that constructs,""" start="00:18:24.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""in my, I'm going to add the word, auto-visualifies them""" start="00:18:30.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""already, auto-defines or something, or just generically""" start="00:18:33.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""wraps function calls some way? already defined. This is""" start="00:18:37.320" video="qanda-transducers" id="subtitle"]]
[[!template text="""basically fold. Some built-in functions like plus already""" start="00:18:42.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""function like reducers. It's a coincidence that they do""" start="00:18:49.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""that. But there's an example in the README. Max is one that""" start="00:18:52.600" video="qanda-transducers" id="subtitle"]]
[[!template text="""does not act like that. For instance, maybe I could screen""" start="00:18:56.800" video="qanda-transducers" id="subtitle"]]
[[!template text="""share later, but if you just type in plus one, If you call plus""" start="00:19:00.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""one in Emacs or Common Lisp, you get back one. It actually""" start="00:19:06.480" video="qanda-transducers" id="subtitle"]]
[[!template text="""only needs one argument. If you only type plus, it actually""" start="00:19:10.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""gives you zero. Plus and multiple satisfy the API of""" start="00:19:15.120" video="qanda-transducers" id="subtitle"]]
[[!template text="""reducers. But if you have one that doesn't, like the max""" start="00:19:20.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""function, and similarly, just type in plus as a function""" start="00:19:24.760" video="qanda-transducers" id="subtitle"]]
[[!template text="""call, just plus with nothing else, and you'll see. No, as a""" start="00:19:28.760" video="qanda-transducers" id="subtitle"]]
[[!template text="""function. zero will come out. This basically means it""" start="00:19:32.360" video="qanda-transducers" id="subtitle"]]
[[!template text="""satisfies the reducer API. But a function like max does not.""" start="00:19:37.200" video="qanda-transducers" id="subtitle"]]
[[!template text="""If you just type in max and then one, it won't work. Pardon me,""" start="00:19:43.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""it did. But if you type in max with nothing else, it wouldn't""" start="00:19:48.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""work.""" start="00:19:54.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""Hence, we have to wrap it in something like fold. I would say""" start="00:19:55.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""go look at the fold function. Right, which that I won't do.""" start="00:19:58.600" video="qanda-transducers" id="subtitle"]]
[[!template text="""I'm not that well enough prepped. Darn it. Leo would have""" start="00:20:01.920" video="qanda-transducers" id="subtitle"]]
[[!template text="""been here, but oh, well, you got me. Yeah, no problem. But""" start="00:20:04.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""fold is sort of the ultimate reducer function. Great. So is""" start="00:20:08.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""there, where was I? Here we go. We're way past this, right? So""" start="00:20:16.880" video="qanda-transducers" id="subtitle"]]

<div class="transcript-heading">[[!template new="1" text="""Q: Is the compelling argument for transducers is that it's a better abstraction?""" start="00:20:26.320" video="qanda-transducers" id="subtitle"]]</div>[[!template text="""is the compiling argument for transducers that it's a""" start="00:20:26.320" video="qanda-transducers" id="subtitle"]]
[[!template text="""better abstraction? It seems like there are concerns,""" start="00:20:34.280" video="qanda-transducers" id="subtitle"]]
[[!template text="""objections, while problematically valid focused on""" start="00:20:38.880" video="qanda-transducers" id="subtitle"]]
[[!template text="""implementation. Can this abstraction allow for advances""" start="00:20:42.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""in implementation? Yes, what I've basically done is mostly""" start="00:20:45.680" video="qanda-transducers" id="subtitle"]]
[[!template text="""followed the pattern of usage that exists in Clojure and in""" start="00:20:50.560" video="qanda-transducers" id="subtitle"]]
[[!template text="""Schemes SERP 171. In theory, the service level API is the""" start="00:20:56.000" video="qanda-transducers" id="subtitle"]]
[[!template text="""same no matter where you're using this, and that's the idea.""" start="00:21:01.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""If you learn them in one list, you should be able to use them""" start="00:21:05.000" video="qanda-transducers" id="subtitle"]]
[[!template text="""everywhere. Then what it's actually doing under the hood is""" start="00:21:08.040" video="qanda-transducers" id="subtitle"]]
[[!template text="""free for us to change around. My implementations are mostly""" start="00:21:12.880" video="qanda-transducers" id="subtitle"]]
[[!template text="""based on the scheme with a few alterations here and there.""" start="00:21:18.360" video="qanda-transducers" id="subtitle"]]
[[!template text="""And in the Common Lisp case, like adding some Common Lisp""" start="00:21:23.680" video="qanda-transducers" id="subtitle"]]
[[!template text="""isms""" start="00:21:27.080" video="qanda-transducers" id="subtitle"]]
[[!template text="""to improve usage like UX a little bit. But overall, we are""" start="00:21:27.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""free to do whatever we want internally to speed up""" start="00:21:34.760" video="qanda-transducers" id="subtitle"]]
[[!template text="""performance. I just haven't done that work. Awesome.""" start="00:21:38.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""Awesome. So here's where I have to, where we're getting the""" start="00:21:42.440" video="qanda-transducers" id="subtitle"]]
[[!template text="""hook. We've just been pulled off the stream. The viewers""" start="00:21:47.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""just saw the crawl by as it sent us over to the other pad where I""" start="00:21:50.080" video="qanda-transducers" id="subtitle"]]
[[!template text="""get to jump on and get involved with that now. But I can't""" start="00:21:54.080" video="qanda-transducers" id="subtitle"]]
[[!template text="""thank you enough, Colin. Would you like me to stop the""" start="00:21:57.920" video="qanda-transducers" id="subtitle"]]
[[!template text="""recording here? Any other comments you'd like to make? Uh,""" start="00:22:00.360" video="qanda-transducers" id="subtitle"]]
[[!template text="""yeah, sure. Like, I mean, I'll stick around for any more live""" start="00:22:03.800" video="qanda-transducers" id="subtitle"]]
[[!template text="""questions. I'm looking at both IRC and, and, um, uh, big blue""" start="00:22:06.440" video="qanda-transducers" id="subtitle"]]
[[!template text="""button here. So if people have more questions, I'll hang""" start="00:22:10.640" video="qanda-transducers" id="subtitle"]]
[[!template text="""around for a bit. I'm going to leave the channel open. I see""" start="00:22:13.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""you do have a few people in here, so I'm just going to go ahead""" start="00:22:15.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""and leave the recording. We can always trim it. Um, trim it""" start="00:22:17.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""up. If you, uh, let us know, Hey, the last 10 minutes weren't""" start="00:22:20.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""anything, you know, or whatever. No, no pressure, no""" start="00:22:24.280" video="qanda-transducers" id="subtitle"]]
[[!template text="""worries, no mistakes. Thank you. Really appreciate you.""" start="00:22:27.000" video="qanda-transducers" id="subtitle"]]
[[!template text="""Yep. Thanks a lot.""" start="00:22:29.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""OK, does anyone else have some questions? I see Mohsen in the""" start="00:22:31.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""BigBlueButton chat is asking how I made the video. So the""" start="00:22:48.400" video="qanda-transducers" id="subtitle"]]
[[!template text="""presentation itself was done with RevealJS from Org Mode.""" start="00:22:52.840" video="qanda-transducers" id="subtitle"]]
[[!template text="""So as you saw, I had a raw Org Mode buffer, which was""" start="00:22:59.080" video="qanda-transducers" id="subtitle"]]
[[!template text="""which was the presentation itself, which I then just""" start="00:23:03.640" video="qanda-transducers" id="subtitle"]]
[[!template text="""exported with a few certain settings, a few""" start="00:23:09.320" video="qanda-transducers" id="subtitle"]]
[[!template text="""customizations. And then for screen recording, I used OBS,""" start="00:23:11.760" video="qanda-transducers" id="subtitle"]]
[[!template text="""which worked flawlessly on Arch Linux. I used Sway,""" start="00:23:15.920" video="qanda-transducers" id="subtitle"]]
[[!template text="""Wayland, and all of that. So all of that just worked, which""" start="00:23:19.720" video="qanda-transducers" id="subtitle"]]
[[!template text="""was very impressive. Where do the HTML host the""" start="00:23:23.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""presentation? I don't have that presentation hosted""" start="00:23:28.000" video="qanda-transducers" id="subtitle"]]
[[!template text="""anywhere.""" start="00:23:51.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""I'll look at the.""" start="00:23:52.600" video="qanda-transducers" id="subtitle"]]
[[!template text="""I don't see that.""" start="00:23:59.120" video="qanda-transducers" id="subtitle"]]
[[!template text="""Here it is. So we've got the file here as well.""" start="00:24:00.080" video="qanda-transducers" id="subtitle"]]
[[!template text="""Looks like that's it for questions, basically.""" start="00:24:08.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""Yep, and it looks like everyone's moved on for now. Let's""" start="00:24:11.000" video="qanda-transducers" id="subtitle"]]
[[!template text="""see. I mean, it would be so this is answering lounge 81 on IRC.""" start="00:24:14.920" video="qanda-transducers" id="subtitle"]]
[[!template text="""Yeah, like, if we really wanted to go that hardcore, maybe""" start="00:24:20.160" video="qanda-transducers" id="subtitle"]]
[[!template text="""there's some like C level stuff that we could""" start="00:24:24.600" video="qanda-transducers" id="subtitle"]]
[[!template text="""you know, significant demand for such a thing. You know, so""" start="00:24:29.440" video="qanda-transducers" id="subtitle"]]
[[!template text="""far there hasn't been such demand, but maybe there will be in""" start="00:24:36.120" video="qanda-transducers" id="subtitle"]]
[[!template text="""the future. Yeah, perhaps there's some custom stuff we""" start="00:24:39.240" video="qanda-transducers" id="subtitle"]]
[[!template text="""could do.""" start="00:24:42.520" video="qanda-transducers" id="subtitle"]]
[[!template text="""And otherwise, magic one.""" start="00:24:43.040" video="qanda-transducers" id="subtitle"]]
[[!template text="""Well, it looks like some people are quite happy with this.""" start="00:24:48.600" video="qanda-transducers" id="subtitle"]]
[[!template text="""All right. That's about what I've seen. So why don't we end it""" start="00:25:00.600" video="qanda-transducers" id="subtitle"]]
[[!template text="""here? I think I can control the recording from my end. If I""" start="00:25:14.960" video="qanda-transducers" id="subtitle"]]
[[!template text="""pause it, will that work? All right. Thank you, everyone.""" start="00:25:19.840" video="qanda-transducers" id="subtitle"]]

</div>Questions or comments? Please e-mail [emacsconf-org-private@gnu.org](mailto:emacsconf-org-private@gnu.org?subject=Comment%20for%20EmacsConf%202023%20transducers%3A%20Transducers%3A%20finally%2C%20ergonomic%20data%20processing%20for%20Emacs%21)


<!-- End of emacsconf-publish-after-page -->