summaryrefslogtreecommitdiffstats
path: root/2023/captions/emacsconf-2023-scheme--bringing-joy-to-scheme-programming--andrew-tropin--main.vtt
blob: 7037754b030e4fd992818df5624a598b4fe3b745 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
WEBVTT captioned by sachac, checked by sachac

NOTE Introduction

00:00:02.120 --> 00:00:07.399
Hello and welcome everyone on EmacsConf 2023.

00:00:07.400 --> 00:00:08.719
I'm Andrew Tropin.

00:00:08.720 --> 00:00:11.919
I work on operating systems and programming languages.

00:00:11.920 --> 00:00:16.639
Today, we discuss Lisps, Schemes, REPLs,

00:00:16.640 --> 00:00:18.139
interactive development,

00:00:18.140 --> 00:00:23.279
and how to make your own cozy development environment.

NOTE Interactive development

00:00:23.280 --> 00:00:26.319
Let's start from interactive development.

00:00:26.320 --> 00:00:29.519
Lisps are famous for a nice

00:00:29.520 --> 00:00:32.479
Interactive Development Experience.

00:00:32.480 --> 00:00:33.999
They have REPLs.

00:00:34.000 --> 00:00:40.119
Emacs Lisp has its own Lisp machine,

00:00:40.120 --> 00:00:44.719
and a lot of cool IDE with different functionality

00:00:44.720 --> 00:00:47.879
is already here and providing

00:00:47.880 --> 00:00:51.619
a nice and pleasant experience.

00:00:51.620 --> 00:00:56.839
The question is, is it enough?

00:00:56.840 --> 00:00:59.920
In most cases, yes, but for some languages,

00:00:59.921 --> 00:01:04.839
we have some white spaces, some missing pieces.

00:01:04.840 --> 00:01:08.299
And for example, in Scheme world,

00:01:08.300 --> 00:01:10.879
we already have a few tools.

00:01:10.880 --> 00:01:14.599
We have REPL, we have integration for REPL in Emacs,

00:01:14.600 --> 00:01:16.679
but is it enough?

00:01:16.680 --> 00:01:18.179
Let's see.

NOTE REPL: Read Eval Print Loop

00:01:18.180 --> 00:01:22.839
We know that Emacs is very good for Lisps and REPL.

00:01:22.840 --> 00:01:26.039
Lisp and Emacs should be a perfect setup.

00:01:26.040 --> 00:01:30.079
But let's see how REPL basically works.

00:01:30.080 --> 00:01:34.799
It's an event loop which does three things.

00:01:34.800 --> 00:01:37.279
It reads an expression, it evaluates the expression,

00:01:37.280 --> 00:01:40.739
and it prints the result.

00:01:40.740 --> 00:01:47.279
We can take a simple expression, input it into REPL,

00:01:47.280 --> 00:01:48.959
and evaluate it and see the result.

00:01:48.960 --> 00:01:50.819
Very nice, very convenient.

00:01:50.820 --> 00:01:55.339
You can experiment and see immediately what is happening.

00:01:55.340 --> 00:01:57.759
You can even run a long-running process

00:01:57.760 --> 00:01:58.919
which does something.

00:01:58.920 --> 00:02:07.199
You can interrupt it and everything will be okay.

00:02:07.200 --> 00:02:08.639
But the problem appears

00:02:08.640 --> 00:02:11.659
when you start to develop a bigger project.

00:02:11.660 --> 00:02:14.039
And in most cases, you don't do

00:02:14.240 --> 00:02:16.399
your whole development in REPL.

00:02:16.400 --> 00:02:18.460
You do only a small part of it.

00:02:18.461 --> 00:02:20.679
In most cases, you just write

00:02:20.680 --> 00:02:22.919
the source code in text files,

00:02:22.920 --> 00:02:26.399
and after that, you run those snippets of code

00:02:26.400 --> 00:02:30.520
from those text files, or run the whole project.

00:02:30.721 --> 00:02:33.719
It's not very convenient to copy and paste

00:02:33.720 --> 00:02:36.039
every time the snippets of code to the REPL,

00:02:36.040 --> 00:02:38.879
see the result, modify the snippet of code,

00:02:38.880 --> 00:02:41.199
copy it again, and so on.

00:02:41.200 --> 00:02:44.039
So people invented some integration

00:02:44.040 --> 00:02:46.079
between REPL and your text editor.

00:02:46.080 --> 00:02:51.599
So you can evaluate expressions inside your text editor

00:02:51.600 --> 00:02:53.719
and see the result here.

NOTE Long-lasting loops

00:02:53.720 --> 00:02:56.679
Works good so far, but what happens

00:02:56.680 --> 00:03:02.299
if we run a long-lasting loop,

00:03:02.300 --> 00:03:04.999
which does a lot of operations.

00:03:05.000 --> 00:03:07.839
As you can see here with a simple example,

00:03:07.840 --> 00:03:13.599
the output of the function,

00:03:13.600 --> 00:03:16.759
stdout of the function is presented here,

00:03:16.760 --> 00:03:18.799
and the resulting value is here.

00:03:18.800 --> 00:03:22.359
If you run a long-running process,

00:03:22.360 --> 00:03:24.639
you don't see anything happening.

00:03:24.640 --> 00:03:29.259
And you see there's a watch instead of my cursor.

00:03:29.260 --> 00:03:33.719
Maybe you don't see it, but nothing actually happens,

00:03:33.720 --> 00:03:36.379
at least from the point of view of the user.

00:03:36.380 --> 00:03:38.399
But if we interrupt the evaluation,

00:03:38.400 --> 00:03:41.439
we will see that some process in the background

00:03:41.440 --> 00:03:44.239
was launched, but we didn't see anything.

00:03:44.240 --> 00:03:51.039
Because the REPL is a single-threaded blocking process,

00:03:51.040 --> 00:03:54.319
which reads stdin and prints stdout,

00:03:54.320 --> 00:03:55.679
make the integration

00:03:55.680 --> 00:03:58.540
between the REPL and your text editor

00:03:58.541 --> 00:04:02.919
is not an easy task.

00:04:02.920 --> 00:04:04.320
And even if you do it,

00:04:04.321 --> 00:04:07.599
you have a lot of downsides, usually.

NOTE Not interruptible

00:04:07.600 --> 00:04:13.679
First of all, the process is not interruptible.

00:04:13.680 --> 00:04:18.479
If you have a remote process which listens on the socket

00:04:18.480 --> 00:04:21.939
to which you connect from your development environment,

00:04:21.940 --> 00:04:25.479
and you run some infinite loop, for example,

00:04:25.480 --> 00:04:28.299
you can't interrupt it.

00:04:28.300 --> 00:04:31.239
Because interruption is done via signals,

00:04:31.240 --> 00:04:35.039
and signals to remote processes are not usually

00:04:35.040 --> 00:04:38.759
the thing in such integrations.

NOTE Output is not interactive

00:04:38.760 --> 00:04:41.159
Output is also not interactive.

00:04:41.160 --> 00:04:45.319
Usually, for example, here you can see

00:04:45.320 --> 00:04:47.799
when I evaluate the expression,

00:04:47.800 --> 00:04:51.119
the output is captured on the evaluation side,

00:04:51.120 --> 00:04:53.719
and after that, after the whole evaluation

00:04:53.720 --> 00:04:56.179
of the whole expression finished,

00:04:56.180 --> 00:05:06.759
I get the result, all the stdout at once.

00:05:06.760 --> 00:05:09.919
And if I run the process which evaluates for 5 seconds,

00:05:09.920 --> 00:05:13.780
I will see the first signs of the life

00:05:13.781 --> 00:05:17.039
only after 5 seconds of evaluation.

00:05:17.040 --> 00:05:23.159
Okay, what else?

NOTE No protocol

00:05:23.160 --> 00:05:26.119
When you do such integrations, you have no protocol,

00:05:26.120 --> 00:05:29.759
you have just stdin and stdout.

00:05:29.760 --> 00:05:32.919
You print to stdin from your text editor.

00:05:32.920 --> 00:05:36.679
You read from stdout of the process.

00:05:36.680 --> 00:05:40.339
It's hard to tell if evaluation is finished,

00:05:40.340 --> 00:05:47.319
if it requires stdin, and how to extend the REPL

00:05:47.320 --> 00:05:51.479
to make it more featureful, and so on.

NOTE Not scalable

00:05:51.480 --> 00:05:57.359
And also, such integrations are usually not very scalable.

00:05:57.360 --> 00:06:14.699
For example, if you want to have a completion,

00:06:14.700 --> 00:06:17.460
you type something, you have the completion. Cool.

00:06:17.461 --> 00:06:22.039
But if you run the process and at the same time

00:06:22.040 --> 00:06:24.620
try to have a completion, you don't have it,

00:06:24.621 --> 00:06:29.799
because the evaluation is in progress,

00:06:29.800 --> 00:06:33.279
and you can't calculate the completion candidates

00:06:33.280 --> 00:06:35.519
at the same time. To make it more obvious,

00:06:35.520 --> 00:06:41.019
I will start a completion here.

00:06:41.020 --> 00:06:43.279
You see the completion pop-ups.

00:06:43.280 --> 00:06:46.159
I start the evaluation process,

00:06:46.160 --> 00:06:49.859
and when I try to complete something,

00:06:49.860 --> 00:06:53.119
the evaluation freezes and there is no completion.

00:06:53.120 --> 00:06:55.479
Not very convenient.

00:06:55.480 --> 00:06:58.119
Usually, you have some long-running processes

00:06:58.120 --> 00:07:01.399
and you want them to continue while you have

00:07:01.400 --> 00:07:08.579
your go to definition, completion, and other things.

00:07:08.580 --> 00:07:13.659
Overall, those issues make it quite inconvenient

00:07:13.660 --> 00:07:18.419
to integrate REPL in text editors or development environments,

00:07:18.420 --> 00:07:21.379
so you need something else

00:07:21.380 --> 00:07:25.859
to make the work comfortable.

NOTE nREPL

00:07:25.860 --> 00:07:28.979
There is already a solution called nREPL.

00:07:28.980 --> 00:07:31.119
It's a synchronous protocol which allows

00:07:31.120 --> 00:07:34.019
to send operations to the server

00:07:34.020 --> 00:07:37.759
and receive responses in a synchronous manner.

00:07:37.760 --> 00:07:42.159
And here is a simple example of a few operations.

00:07:42.160 --> 00:07:45.079
First one is cloning the existing session,

00:07:45.080 --> 00:07:49.240
and as a response you will get a new session.

00:07:49.241 --> 00:07:52.099
Also you send the evaluation request with code

00:07:52.100 --> 00:07:55.639
that you want to evaluate, and you get two responses.

00:07:55.640 --> 00:08:00.600
First one says that output is captured

00:08:00.601 --> 00:08:02.839
and it's equal to "hi\n",

00:08:02.840 --> 00:08:06.560
and after that, you receive an "Evaluation completed",

00:08:06.561 --> 00:08:12.439
the value of this expression.

00:08:12.440 --> 00:08:14.079
This protocol was developed

00:08:14.080 --> 00:08:15.879
for CIDER development environment.

00:08:15.880 --> 00:08:18.759
It's a Clojure development environment for Emacs.

00:08:18.760 --> 00:08:22.859
It's very cool, featureful, reliable,

00:08:22.860 --> 00:08:26.899
and I would say production-ready.

00:08:26.900 --> 00:08:31.499
A lot of professional Clojure developers use it.

00:08:31.500 --> 00:08:33.239
The nREPL protocol is very simple.

00:08:33.240 --> 00:08:38.219
It has a few operations out of the box,

00:08:38.220 --> 00:08:46.479
and you can extend it with any arbitrary operation you want.

00:08:46.480 --> 00:08:53.819
I work a lot on Guix codebase and other Scheme projects,

00:08:53.820 --> 00:08:57.299
so the experience I had previously with nREPL

00:08:57.300 --> 00:08:59.399
was not satisfying. I decided

00:08:59.400 --> 00:09:01.739
to just implement nREPL protocol.

NOTE Arei, Ares, and how to try

00:09:01.740 --> 00:09:05.719
First of all, I implemented nREPL server in Guile.

00:09:05.720 --> 00:09:11.339
I called it `guile-ares-rs`, and used it

00:09:11.340 --> 00:09:13.959
with a generic nREPL client for Emacs.

00:09:13.960 --> 00:09:14.719
It worked.

00:09:14.720 --> 00:09:18.639
It had some rough edges, but overall it was okay.

00:09:18.640 --> 00:09:21.639
And after that, to add more features

00:09:21.640 --> 00:09:25.079
to make the implementation more complete,

00:09:25.080 --> 00:09:33.219
I wrote my own nREPL client for Emacs and called it `arei`.

00:09:33.220 --> 00:09:40.179
And I got almost complete Guile IDE in two months.

00:09:40.180 --> 00:09:45.319
So `ares-rs` is nREPL server implementation.

00:09:45.320 --> 00:09:49.679
`arei` is Emacs client, which uses the same nREPL protocol.

00:09:49.680 --> 00:09:54.439
It utilizes `sesman` package for managing sessions,

00:09:54.440 --> 00:10:00.079
the association of buffers with nREPL connection.

00:10:00.080 --> 00:10:04.379
It has some roots.

00:10:04.380 --> 00:10:06.639
The implementation has some roots

00:10:06.640 --> 00:10:09.979
in Geiser, CIDER, Monroe, and Rail.

00:10:09.980 --> 00:10:15.279
I took small snippets for some parts of functionality.

00:10:15.280 --> 00:10:19.479
I used the CAPF and xref infrastructure

00:10:19.480 --> 00:10:23.079
for completion at point and cross-reference capabilities.

00:10:23.080 --> 00:10:27.679
And by the time of conference, I hope

00:10:27.680 --> 00:10:30.199
that README will be complete enough

00:10:30.200 --> 00:10:34.179
so you will be able to try it yourself.

NOTE Demo

00:10:34.180 --> 00:10:42.679
Let's see what is possible with it already.

00:10:42.680 --> 00:10:46.719
Let's connect to nREPL server.

00:10:51.900 --> 00:10:56.280
After that, you can evaluate the expression.

00:10:56.281 --> 00:11:02.319
And you see the stdout and the result.

00:11:02.320 --> 00:11:04.719
Very nice, very convenient.

00:11:04.720 --> 00:11:08.659
You have different expression, you evaluate it,

00:11:08.660 --> 00:11:10.359
you get the value of the evaluation.

00:11:10.360 --> 00:11:12.279
You can run an infinite loop

00:11:12.280 --> 00:11:15.639
which prints to stderr and stdout

00:11:15.640 --> 00:11:18.599
and you see all necessary stuff.

00:11:18.600 --> 00:11:19.299
Very cool.

00:11:19.300 --> 00:11:21.959
But also, you can interrupt the evaluation,

00:11:21.960 --> 00:11:25.159
which is very convenient if you accidentally

00:11:25.160 --> 00:11:27.639
run an infinite loop.

NOTE Continuations

00:11:27.640 --> 00:11:32.939
Also, do you remember here we have a few more examples

00:11:32.940 --> 00:11:34.079
that we didn't try yet?

00:11:34.080 --> 00:11:39.159
For example, on usual REPL implementation,

00:11:39.160 --> 00:11:47.599
if I evaluate this expression, I get return value.

00:11:47.600 --> 00:11:50.759
I make a continuation and save it to this variable

00:11:50.760 --> 00:11:52.859
and I try to call this evaluation

00:11:52.860 --> 00:11:55.339
and I get an exception,

00:11:55.340 --> 00:11:58.399
because the environment in which this continuation

00:11:58.400 --> 00:12:03.479
was created was different and it has redefined

00:12:03.480 --> 00:12:06.159
stdout and stderr to capture it.

00:12:06.160 --> 00:12:08.979
But when I run it one more time,

00:12:08.980 --> 00:12:12.199
when I resume the continuation,

00:12:12.200 --> 00:12:15.799
the environment changed and it doesn't work.

00:12:15.800 --> 00:12:17.419
What happens in `arei`?

00:12:17.420 --> 00:12:21.759
I define continuation, I save the continuation

00:12:21.760 --> 00:12:23.479
for the simple expression

00:12:23.480 --> 00:12:27.279
and I resume the continuation with a new argument,

00:12:27.280 --> 00:12:30.139
and you can see at the top of the screen

00:12:30.140 --> 00:12:32.459
that it works perfectly fine.

NOTE Reading from stdin

00:12:32.460 --> 00:12:35.559
Also, with a usual REPL implementation,

00:12:35.560 --> 00:12:40.319
let's see what happens when we have a process

00:12:40.320 --> 00:12:41.919
which reads from stdin.

00:12:41.920 --> 00:12:48.099
I evaluate the expression and nothing visible happens.

00:12:48.100 --> 00:12:52.999
I can try to type `C-g`, `C-c`,

00:12:53.000 --> 00:12:56.559
and after some time it will say user interrupt.

00:12:56.560 --> 00:13:00.439
What actually I expect in such a case

00:13:00.440 --> 00:13:04.679
to have a minibuffer which prompts me for the input.

00:13:04.680 --> 00:13:10.019
When I evaluate the same expression in the `arei`,

00:13:10.020 --> 00:13:12.199
you see the prompt at the minibuffer

00:13:12.200 --> 00:13:21.899
and here I can tell, "Hello I'm a message from minibuffer".

00:13:21.900 --> 00:13:26.099
Cool. You will see that this message is printed to stdout,

00:13:26.100 --> 00:13:28.679
and unspecified was returned

00:13:28.680 --> 00:13:33.419
as a result of this expression.

NOTE Fancy example with continuations

00:13:33.420 --> 00:13:37.319
Let's make some fancy example with continuations.

00:13:37.320 --> 00:13:45.079
Continuations is a very cool mechanism

00:13:45.080 --> 00:13:47.999
which is not the topic of today's talk,

00:13:48.000 --> 00:13:50.999
but you can find a lot of interesting information

00:13:51.000 --> 00:13:54.439
in Scheme documentation or in related books,

00:13:54.440 --> 00:13:58.339
and I advise you to do it because it's really nice thing

00:13:58.340 --> 00:14:00.119
that is actually applicable

00:14:00.120 --> 00:14:03.519
in many different programming languages.

00:14:03.520 --> 00:14:05.199
Here you can see the infinite loop

00:14:05.200 --> 00:14:09.159
which just prints values increasing one by one.

00:14:09.160 --> 00:14:13.299
And here we save a continuation on each iteration.

00:14:13.300 --> 00:14:18.059
I can call the continuation

00:14:18.060 --> 00:14:21.939
and it will resume from the previous saved step.

00:14:21.940 --> 00:14:27.679
And you can see, it resumed from the same step

00:14:27.680 --> 00:14:31.640
we interrupted earlier, but we provided a new value for it.
another value for it.

00:14:31.641 --> 00:14:33.920
We can provide another value

00:14:33.921 --> 00:14:39.199
and it resumed from the same spot it was saved earlier.

00:14:39.200 --> 00:14:42.579
But I also can provide a `read-i` value

00:14:42.580 --> 00:14:45.199
and if I provide `read-i` value,

00:14:45.200 --> 00:14:50.779
the infinite loop will read the input from stdin

00:14:50.780 --> 00:14:53.319
and will continue the evaluation

00:14:53.320 --> 00:14:56.679
with a different `i` provided in this input.

00:14:56.680 --> 00:15:03.039
So let's try to type some arbitrary value

00:15:03.040 --> 00:15:07.519
and you see that the loop continued with this value.

00:15:07.520 --> 00:15:08.039
Very nice.

00:15:08.040 --> 00:15:13.159
And every time we could easily interrupt it.

NOTE Guix API

00:15:13.160 --> 00:15:17.319
Okay, what most annoying thing that I had previously

00:15:17.320 --> 00:15:19.339
with the usual REPL implementation

00:15:19.340 --> 00:15:22.759
that I have a quite nice Guix API

00:15:22.760 --> 00:15:27.579
where I can build packages, systems and other stuff.

00:15:27.580 --> 00:15:35.359
But if I evaluate this expression, I will get an error.

00:15:35.360 --> 00:15:38.039
Okay. I will get an error

00:15:38.040 --> 00:15:44.479
because I don't have an appropriate environment.

00:15:44.480 --> 00:15:51.579
But what I can do, I can connect to the remote REPL

00:15:51.580 --> 00:15:55.059
by creating a server with `guix repl --listen` command

00:15:55.060 --> 00:15:58.619
and connecting to it with `geiser-connect` command.

00:15:58.620 --> 00:16:01.819
And now I can evaluate this expression.

00:16:01.820 --> 00:16:03.359
Right?

00:16:03.360 --> 00:16:10.479
Wow.

00:16:10.480 --> 00:16:14.339
Okay.

00:16:14.340 --> 00:16:19.039
It actually doesn't matter for my example.

00:16:19.040 --> 00:16:22.879
I will explain how it doesn't work easily.

00:16:22.880 --> 00:16:26.519
This is a long-running process which prints something

00:16:26.520 --> 00:16:29.579
and it can take up to a few minutes.

00:16:29.580 --> 00:16:33.359
And for the whole few minutes I don't see any results,

00:16:33.360 --> 00:16:38.719
the same as with this infinite loop which prints to stdout

00:16:38.720 --> 00:16:42.199
but I don't see anything interactively.

00:16:42.200 --> 00:16:45.619
With `arei`, I can run

00:16:45.620 --> 00:16:47.920
the evaluation of the same expression,

00:16:51.440 --> 00:16:54.119
and you will see instantly

00:16:54.120 --> 00:17:00.200
that stdout is presented here in slightly yellowish color.

00:17:00.201 --> 00:17:02.920
I can interrupt the evaluation

00:17:02.921 --> 00:17:06.039
if I don't want to wait until it's finished,

00:17:06.040 --> 00:17:15.779
and just after that, I can evaluate another value.

00:17:15.780 --> 00:17:23.359
So that's cool.

00:17:23.360 --> 00:17:25.959
And let's see one more thing.

00:17:25.960 --> 00:17:30.339
We have an infinite loop and we have some completion here.

00:17:30.340 --> 00:17:32.579
And completion still works,

00:17:32.580 --> 00:17:33.659
very nice,

00:17:33.660 --> 00:17:40.259
while the infinite loop is running.

00:17:40.260 --> 00:17:42.059
Okay.

NOTE Support

00:17:42.060 --> 00:17:44.919
Actually it took me around two months

00:17:44.920 --> 00:17:48.039
of full-time work funded by my own savings,

00:17:48.040 --> 00:17:51.599
and you can support and help to the project

00:17:51.600 --> 00:17:57.019
using OpenCollective or by contributing on SourceHut.

NOTE Future steps - Multiple simultaneous evaluations in different contexts

00:17:57.020 --> 00:17:58.699
The future steps for the project

00:17:58.700 --> 00:18:03.674
include an experimental workflow where you have

00:18:03.675 --> 00:18:07.539
multiple simultaneous evaluation in different contexts.

00:18:07.540 --> 00:18:11.959
For example, you have Fibers, you have Goblins,

00:18:11.960 --> 00:18:16.919
you have some HTTP server or some other thing,

00:18:16.920 --> 00:18:22.119
and you want to run all of them independently

00:18:22.120 --> 00:18:25.319
in slightly isolated sessions,

00:18:25.320 --> 00:18:29.799
and you want to have the ability

00:18:29.800 --> 00:18:30.959
to still interact with them.

00:18:30.960 --> 00:18:33.979
For example, if they require standard input

00:18:33.980 --> 00:18:39.239
or something else, you want to be able to provide it.

00:18:39.240 --> 00:18:42.519
You want to see the stderr and stdout

00:18:42.520 --> 00:18:46.219
of those long-running processes and so on.

NOTE Tree-sitter integration

00:18:46.220 --> 00:18:50.239
The second thing is tree-sitter integration

00:18:50.240 --> 00:18:53.399
for better syntax highlighting, code navigation,

00:18:53.400 --> 00:18:56.879
and other features.

NOTE Full-fledged debugger

00:18:56.880 --> 00:19:01.399
And after that, probably we will do a full-fledged debugger

00:19:01.400 --> 00:19:06.239
so you can jump expressions one by one

00:19:06.240 --> 00:19:10.779
and see the results and see some intermediate values

00:19:10.780 --> 00:19:13.079
during the evaluation.

00:19:13.080 --> 00:19:14.479
And it's very possible

00:19:14.480 --> 00:19:17.079
because nREPL is a very extensible protocol

00:19:17.080 --> 00:19:18.199
and you can implement

00:19:18.200 --> 00:19:22.759
whatever you want on top of it.

NOTE FAQ - Does it support other Scheme implementations?

00:19:22.760 --> 00:19:27.079
I will answer two probably very frequent questions.

00:19:27.080 --> 00:19:30.499
Does it support other Scheme implementations?

00:19:30.500 --> 00:19:32.279
At the moment, it doesn't,

00:19:32.280 --> 00:19:36.519
but the Scheme implementation is not restricted.

00:19:36.520 --> 00:19:40.639
You have a server which is implemented in your language

00:19:40.640 --> 00:19:43.974
and you have a client--in our case, `arei`--

00:19:43.975 --> 00:19:48.319
which communicates with this protocol.

00:19:48.320 --> 00:19:52.359
So if you implement nREPL server in a different language,

00:19:52.360 --> 00:19:58.379
it should work with already implemented `arei` client.

NOTE Is it possible to use it with other text editors?

00:19:58.380 --> 00:20:04.079
And is it possible to use the same functionality

00:20:04.080 --> 00:20:06.999
in other text editors, for example in VS Code,

00:20:07.000 --> 00:20:08.679
Vim, whatever?

00:20:08.680 --> 00:20:13.799
Yes, it's possible and the case is similar here.

00:20:13.800 --> 00:20:16.599
You have already implemented nREPL server

00:20:16.600 --> 00:20:19.359
and you can write your own nREPL client

00:20:19.360 --> 00:20:22.120
in a different text editor and it will work.

NOTE Conclusion

00:20:22.121 --> 00:20:26.759
I would like to thank the authors and maintainers

00:20:26.760 --> 00:20:30.439
and contributors of Guile, Geiser, CIDER, Clojure,

00:20:30.440 --> 00:20:33.359
and Emacs, and all other people

00:20:33.360 --> 00:20:38.779
who are somehow related to the work on those projects

00:20:38.780 --> 00:20:42.079
involved in this talk.

00:20:42.080 --> 00:20:45.879
And I hope the Scheme programming will be enjoyable.

NOTE Contacts

00:20:45.880 --> 00:20:47.239
If you want to contact me,

00:20:47.240 --> 00:20:49.799
join #tropin IRC channel at libera.chat,

00:20:49.800 --> 00:20:53.039
or drop me a message via email or feediverse

00:20:53.040 --> 00:20:55.879
using `andrew@trop.in` handle.

00:20:55.880 --> 00:21:00.680
I will see you in a bit in Q&A session.