From 543807855cd595c6ceffbcc07bf4b7fab67e396a Mon Sep 17 00:00:00 2001 From: EmacsConf Date: Sun, 3 Dec 2023 10:00:22 -0500 Subject: Automated commit --- ...-programming--andrew-tropin--main--chapters.vtt | 68 ++ ...-to-scheme-programming--andrew-tropin--main.vtt | 1044 ++++++++++++++++++++ 2023/info/scheme-after.md | 341 +++++++ 2023/info/scheme-before.md | 26 +- 4 files changed, 1478 insertions(+), 1 deletion(-) create mode 100644 2023/captions/emacsconf-2023-scheme--bringing-joy-to-scheme-programming--andrew-tropin--main--chapters.vtt create mode 100644 2023/captions/emacsconf-2023-scheme--bringing-joy-to-scheme-programming--andrew-tropin--main.vtt (limited to '2023') diff --git a/2023/captions/emacsconf-2023-scheme--bringing-joy-to-scheme-programming--andrew-tropin--main--chapters.vtt b/2023/captions/emacsconf-2023-scheme--bringing-joy-to-scheme-programming--andrew-tropin--main--chapters.vtt new file mode 100644 index 00000000..15bb79f9 --- /dev/null +++ b/2023/captions/emacsconf-2023-scheme--bringing-joy-to-scheme-programming--andrew-tropin--main--chapters.vtt @@ -0,0 +1,68 @@ +WEBVTT + + +00:00:02.120 --> 00:00:23.279 +Introduction + +00:00:23.280 --> 00:01:18.179 +Interactive development + +00:01:18.180 --> 00:02:53.719 +REPL: Read Eval Print Loop + +00:02:53.720 --> 00:04:07.599 +Long-lasting loops + +00:04:07.600 --> 00:05:23.159 +Not interruptible + +00:05:23.160 --> 00:05:51.479 +No protocol + +00:05:51.480 --> 00:07:25.859 +Not scalable + +00:07:25.860 --> 00:09:01.739 +nREPL + +00:09:01.740 --> 00:10:34.179 +Arei, Ares, and how to try + +00:10:34.180 --> 00:11:27.639 +Demo + +00:11:27.640 --> 00:12:32.459 +Continuations + +00:12:32.460 --> 00:13:33.419 +Reading from stdin + +00:13:33.420 --> 00:15:13.159 +Fancy example with continuations + +00:15:13.160 --> 00:17:42.059 +Guix API + +00:17:42.060 --> 00:17:57.019 +Support + +00:17:57.020 --> 00:18:46.219 +Future steps - Multiple simultaneous evaluations in different contexts + +00:18:46.220 --> 00:18:56.879 +Tree-sitter integration + +00:18:56.880 --> 00:19:22.759 +Full-fledged debugger + +00:19:22.760 --> 00:19:58.379 +FAQ - Does it support other Scheme implementations? + +00:19:58.380 --> 00:20:22.120 +Is it possible to use it with other text editors? + +00:20:22.121 --> 00:20:45.879 +Conclusion + +00:20:45.880 --> 00:21:00.680 +Contacts diff --git a/2023/captions/emacsconf-2023-scheme--bringing-joy-to-scheme-programming--andrew-tropin--main.vtt b/2023/captions/emacsconf-2023-scheme--bringing-joy-to-scheme-programming--andrew-tropin--main.vtt new file mode 100644 index 00000000..8423ba94 --- /dev/null +++ b/2023/captions/emacsconf-2023-scheme--bringing-joy-to-scheme-programming--andrew-tropin--main.vtt @@ -0,0 +1,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. + +NOT 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. diff --git a/2023/info/scheme-after.md b/2023/info/scheme-after.md index f1d3edb1..b4ca3d31 100644 --- a/2023/info/scheme-after.md +++ b/2023/info/scheme-after.md @@ -1,6 +1,347 @@ + +# Transcript + +[[!template new="1" text="""Hello and welcome everyone on EmacsConf 2023.""" start="00:00:02.120" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I'm Andrew Tropin.""" start="00:00:07.400" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I work on operating systems and programming languages.""" start="00:00:08.720" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Today, we discuss Lisps, Schemes, REPLs,""" start="00:00:11.920" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""interactive development,""" start="00:00:16.640" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and how to make your own cozy development environment.""" start="00:00:18.140" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""Let's start from interactive development.""" start="00:00:23.280" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Lisps are famous for a nice""" start="00:00:26.320" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Interactive Development Experience.""" start="00:00:29.520" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""They have REPLs.""" start="00:00:32.480" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Emacs Lisp has its own Lisp machine,""" start="00:00:34.000" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and a lot of cool IDE with different functionality""" start="00:00:40.120" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""is already here and providing""" start="00:00:44.720" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""a nice and pleasant experience.""" start="00:00:47.880" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""The question is, is it enough?""" start="00:00:51.620" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""In most cases, yes, but for some languages,""" start="00:00:56.840" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""we have some white spaces, some missing pieces.""" start="00:00:59.921" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And for example, in Scheme world,""" start="00:01:04.840" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""we already have a few tools.""" start="00:01:08.300" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""We have REPL, we have integration for REPL in Emacs,""" start="00:01:10.880" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""but is it enough?""" start="00:01:14.600" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Let's see.""" start="00:01:16.680" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""We know that Emacs is very good for Lisps and REPL.""" start="00:01:18.180" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Lisp and Emacs should be a perfect setup.""" start="00:01:22.840" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""But let's see how REPL basically works.""" start="00:01:26.040" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""It's an event loop which does three things.""" start="00:01:30.080" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""It reads an expression, it evaluates the expression,""" start="00:01:34.800" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and it prints the result.""" start="00:01:37.280" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""We can take a simple expression, input it into REPL,""" start="00:01:40.740" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and evaluate it and see the result.""" start="00:01:47.280" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Very nice, very convenient.""" start="00:01:48.960" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""You can experiment and see immediately what is happening.""" start="00:01:50.820" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""You can even run a long-running process""" start="00:01:55.340" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""which does something.""" start="00:01:57.760" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""You can interrupt it and everything will be okay.""" start="00:01:58.920" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""But the problem appears""" start="00:02:07.200" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""when you start to develop a bigger project.""" start="00:02:08.640" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And in most cases, you don't do""" start="00:02:11.660" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""your whole development in REPL.""" start="00:02:14.240" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""You do only a small part of it.""" start="00:02:16.400" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""In most cases, you just write""" start="00:02:18.461" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""the source code in text files,""" start="00:02:20.680" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and after that, you run those snippets of code""" start="00:02:22.920" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""from those text files, or run the whole project.""" start="00:02:26.400" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""It's not very convenient to copy and paste""" start="00:02:30.721" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""every time the snippets of code to the REPL,""" start="00:02:33.720" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""see the result, modify the snippet of code,""" start="00:02:36.040" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""copy it again, and so on.""" start="00:02:38.880" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""So people invented some integration""" start="00:02:41.200" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""between REPL and your text editor.""" start="00:02:44.040" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""So you can evaluate expressions inside your text editor""" start="00:02:46.080" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and see the result here.""" start="00:02:51.600" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""Works good so far, but what happens""" start="00:02:53.720" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""if we run a long-lasting loop,""" start="00:02:56.680" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""which does a lot of operations.""" start="00:03:02.300" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""As you can see here with a simple example,""" start="00:03:05.000" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""the output of the function,""" start="00:03:07.840" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""stdout of the function is presented here,""" start="00:03:13.600" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and the resulting value is here.""" start="00:03:16.760" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""If you run a long-running process,""" start="00:03:18.800" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""you don't see anything happening.""" start="00:03:22.360" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And you see there's a watch instead of my cursor.""" start="00:03:24.640" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Maybe you don't see it, but nothing actually happens,""" start="00:03:29.260" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""at least from the point of view of the user.""" start="00:03:33.720" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""But if we interrupt the evaluation,""" start="00:03:36.380" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""we will see that some process in the background""" start="00:03:38.400" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""was launched, but we didn't see anything.""" start="00:03:41.440" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Because the REPL is a single-threaded blocking process,""" start="00:03:44.240" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""which reads stdin and prints stdout,""" start="00:03:51.040" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""make the integration""" start="00:03:54.320" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""between the REPL and your text editor""" start="00:03:55.680" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""is not an easy task.""" start="00:03:58.541" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And even if you do it,""" start="00:04:02.920" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""you have a lot of downsides, usually.""" start="00:04:04.321" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""First of all, the process is not interruptible.""" start="00:04:07.600" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""If you have a remote process which listens on the socket""" start="00:04:13.680" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""to which you connect from your development environment,""" start="00:04:18.480" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and you run some infinite loop, for example,""" start="00:04:21.940" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""you can't interrupt it.""" start="00:04:25.480" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Because interruption is done via signals,""" start="00:04:28.300" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and signals to remote processes are not usually""" start="00:04:31.240" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""the thing in such integrations.""" start="00:04:35.040" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Output is also not interactive.""" start="00:04:38.760" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Usually, for example, here you can see""" start="00:04:41.160" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""when I evaluate the expression,""" start="00:04:45.320" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""the output is captured on the evaluation side,""" start="00:04:47.800" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and after that, after the whole evaluation""" start="00:04:51.120" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""of the whole expression finished,""" start="00:04:53.720" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I get the result, all the stdout at once.""" start="00:04:56.180" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And if I run the process which evaluates for 5 seconds,""" start="00:05:06.760" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I will see the first signs of the life""" start="00:05:09.920" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""only after 5 seconds of evaluation.""" start="00:05:13.781" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Okay, what else?""" start="00:05:17.040" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""When you do such integrations, you have no protocol,""" start="00:05:23.160" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""you have just stdin and stdout.""" start="00:05:26.120" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""You print to stdin from your text editor.""" start="00:05:29.760" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""You read from stdout of the process.""" start="00:05:32.920" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""It's hard to tell if evaluation is finished,""" start="00:05:36.680" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""if it requires stdin, and how to extend the REPL""" start="00:05:40.340" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""to make it more featureful, and so on.""" start="00:05:47.320" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""And also, such integrations are usually not very scalable.""" start="00:05:51.480" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""For example, if you want to have a completion,""" start="00:05:57.360" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""you type something, you have the completion. Cool.""" start="00:06:14.700" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""But if you run the process and at the same time""" start="00:06:17.461" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""try to have a completion, you don't have it,""" start="00:06:22.040" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""because the evaluation is in progress,""" start="00:06:24.621" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and you can't calculate the completion candidates""" start="00:06:29.800" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""at the same time. To make it more obvious,""" start="00:06:33.280" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I will start a completion here.""" start="00:06:35.520" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""You see the completion pop-ups.""" start="00:06:41.020" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I start the evaluation process,""" start="00:06:43.280" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and when I try to complete something,""" start="00:06:46.160" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""the evaluation freezes and there is no completion.""" start="00:06:49.860" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Not very convenient.""" start="00:06:53.120" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Usually, you have some long-running processes""" start="00:06:55.480" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and you want them to continue while you have""" start="00:06:58.120" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""your go to definition, completion, and other things.""" start="00:07:01.400" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Overall, those issues make it quite inconvenient""" start="00:07:08.580" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""to integrate REPL in text editors or development environments,""" start="00:07:13.660" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""so you need something else""" start="00:07:18.420" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""to make the work comfortable.""" start="00:07:21.380" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""There is already a solution called nREPL.""" start="00:07:25.860" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""It's a synchronous protocol which allows""" start="00:07:28.980" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""to send operations to the server""" start="00:07:31.120" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and receive responses in a synchronous manner.""" start="00:07:34.020" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And here is a simple example of a few operations.""" start="00:07:37.760" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""First one is cloning the existing session,""" start="00:07:42.160" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and as a response you will get a new session.""" start="00:07:45.080" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Also you send the evaluation request with code""" start="00:07:49.241" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""that you want to evaluate, and you get two responses.""" start="00:07:52.100" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""First one says that output is captured""" start="00:07:55.640" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and it's equal to "hi\n",""" start="00:08:00.601" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and after that, you receive an "Evaluation completed",""" start="00:08:02.840" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""the value of this expression.""" start="00:08:06.561" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""This protocol was developed""" start="00:08:12.440" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""for CIDER development environment.""" start="00:08:14.080" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""It's a Clojure development environment for Emacs.""" start="00:08:15.880" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""It's very cool, featureful, reliable,""" start="00:08:18.760" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and I would say production-ready.""" start="00:08:22.860" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""A lot of professional Clojure developers use it.""" start="00:08:26.900" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""The nREPL protocol is very simple.""" start="00:08:31.500" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""It has a few operations out of the box,""" start="00:08:33.240" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and you can extend it with any arbitrary operation you want.""" start="00:08:38.220" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I work a lot on Guix codebase and other Scheme projects,""" start="00:08:46.480" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""so the experience I had previously with nREPL""" start="00:08:53.820" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""was not satisfying. I decided""" start="00:08:57.300" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""to just implement nREPL protocol.""" start="00:08:59.400" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""First of all, I implemented nREPL server in Guile.""" start="00:09:01.740" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I called it `guile-ares-rs`, and used it""" start="00:09:05.720" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""with a generic nREPL client for Emacs.""" start="00:09:11.340" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""It worked.""" start="00:09:13.960" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""It had some rough edges, but overall it was okay.""" start="00:09:14.720" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And after that, to add more features""" start="00:09:18.640" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""to make the implementation more complete,""" start="00:09:21.640" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I wrote my own nREPL client for Emacs and called it `arei`.""" start="00:09:25.080" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And I got almost complete Guile IDE in two months.""" start="00:09:33.220" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""So `ares-rs` is nREPL server implementation.""" start="00:09:40.180" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""`arei` is Emacs client, which uses the same nREPL protocol.""" start="00:09:45.320" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""It utilizes `sesman` package for managing sessions,""" start="00:09:49.680" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""the association of buffers with nREPL connection.""" start="00:09:54.440" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""It has some roots.""" start="00:10:00.080" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""The implementation has some roots""" start="00:10:04.380" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""in Geiser, CIDER, Monroe, and Rail.""" start="00:10:06.640" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I took small snippets for some parts of functionality.""" start="00:10:09.980" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I used the CAPF and xref infrastructure""" start="00:10:15.280" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""for completion at point and cross-reference capabilities.""" start="00:10:19.480" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And by the time of conference, I hope""" start="00:10:23.080" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""that README will be complete enough""" start="00:10:27.680" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""so you will be able to try it yourself.""" start="00:10:30.200" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""Let's see what is possible with it already.""" start="00:10:34.180" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Let's connect to nREPL server.""" start="00:10:42.680" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""After that, you can evaluate the expression.""" start="00:10:51.900" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And you see the stdout and the result.""" start="00:10:56.281" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Very nice, very convenient.""" start="00:11:02.320" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""You have different expression, you evaluate it,""" start="00:11:04.720" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""you get the value of the evaluation.""" start="00:11:08.660" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""You can run an infinite loop""" start="00:11:10.360" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""which prints to stderr and stdout""" start="00:11:12.280" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and you see all necessary stuff.""" start="00:11:15.640" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Very cool.""" start="00:11:18.600" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""But also, you can interrupt the evaluation,""" start="00:11:19.300" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""which is very convenient if you accidentally""" start="00:11:21.960" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""run an infinite loop.""" start="00:11:25.160" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""Also, do you remember here we have a few more examples""" start="00:11:27.640" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""that we didn't try yet?""" start="00:11:32.940" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""For example, on usual REPL implementation,""" start="00:11:34.080" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""if I evaluate this expression, I get return value.""" start="00:11:39.160" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I make a continuation and save it to this variable""" start="00:11:47.600" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and I try to call this evaluation""" start="00:11:50.760" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and I get an exception,""" start="00:11:52.860" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""because the environment in which this continuation""" start="00:11:55.340" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""was created was different and it has redefined""" start="00:11:58.400" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""stdout and stderr to capture it.""" start="00:12:03.480" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""But when I run it one more time,""" start="00:12:06.160" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""when I resume the continuation,""" start="00:12:08.980" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""the environment changed and it doesn't work.""" start="00:12:12.200" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""What happens in `arei`?""" start="00:12:15.800" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I define continuation, I save the continuation""" start="00:12:17.420" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""for the simple expression""" start="00:12:21.760" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and I resume the continuation with a new argument,""" start="00:12:23.480" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and you can see at the top of the screen""" start="00:12:27.280" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""that it works perfectly fine.""" start="00:12:30.140" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""Also, with a usual REPL implementation,""" start="00:12:32.460" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""let's see what happens when we have a process""" start="00:12:35.560" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""which reads from stdin.""" start="00:12:40.320" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I evaluate the expression and nothing visible happens.""" start="00:12:41.920" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I can try to type `C-g`, `C-c`,""" start="00:12:48.100" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and after some time it will say user interrupt.""" start="00:12:53.000" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""What actually I expect in such a case""" start="00:12:56.560" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""to have a minibuffer which prompts me for the input.""" start="00:13:00.440" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""When I evaluate the same expression in the `arei`,""" start="00:13:04.680" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""you see the prompt at the minibuffer""" start="00:13:10.020" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and here I can tell, "Hello I'm a message from minibuffer".""" start="00:13:12.200" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Cool. You will see that this message is printed to stdout,""" start="00:13:21.900" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and unspecified was returned""" start="00:13:26.100" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""as a result of this expression.""" start="00:13:28.680" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""Let's make some fancy example with continuations.""" start="00:13:33.420" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Continuations is a very cool mechanism""" start="00:13:37.320" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""which is not the topic of today's talk,""" start="00:13:45.080" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""but you can find a lot of interesting information""" start="00:13:48.000" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""in Scheme documentation or in related books,""" start="00:13:51.000" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and I advise you to do it because it's really nice thing""" start="00:13:54.440" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""that is actually applicable""" start="00:13:58.340" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""in many different programming languages.""" start="00:14:00.120" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Here you can see the infinite loop""" start="00:14:03.520" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""which just prints values increasing one by one.""" start="00:14:05.200" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And here we save a continuation on each iteration.""" start="00:14:09.160" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I can call the continuation""" start="00:14:13.300" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and it will resume from the previous saved step.""" start="00:14:18.060" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And you can see, it resumed from the same step""" start="00:14:21.940" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""we interrupted earlier, but we provided a new value for it. +another value for it.""" start="00:14:27.680" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""We can provide another value""" start="00:14:31.641" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and it resumed from the same spot it was saved earlier.""" start="00:14:33.921" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""But I also can provide a `read-i` value""" start="00:14:39.200" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and if I provide `read-i` value,""" start="00:14:42.580" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""the infinite loop will read the input from stdin""" start="00:14:45.200" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and will continue the evaluation""" start="00:14:50.780" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""with a different `i` provided in this input.""" start="00:14:53.320" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""So let's try to type some arbitrary value""" start="00:14:56.680" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and you see that the loop continued with this value.""" start="00:15:03.040" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Very nice.""" start="00:15:07.520" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And every time we could easily interrupt it.""" start="00:15:08.040" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""Okay, what most annoying thing that I had previously""" start="00:15:13.160" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""with the usual REPL implementation""" start="00:15:17.320" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""that I have a quite nice Guix API""" start="00:15:19.340" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""where I can build packages, systems and other stuff.""" start="00:15:22.760" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""But if I evaluate this expression, I will get an error.""" start="00:15:27.580" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Okay. I will get an error""" start="00:15:35.360" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""because I don't have an appropriate environment.""" start="00:15:38.040" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""But what I can do, I can connect to the remote REPL""" start="00:15:44.480" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""by creating a server with `guix repl --listen` command""" start="00:15:51.580" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and connecting to it with `geiser-connect` command.""" start="00:15:55.060" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And now I can evaluate this expression.""" start="00:15:58.620" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Right?""" start="00:16:01.820" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Wow.""" start="00:16:03.360" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Okay.""" start="00:16:10.480" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""It actually doesn't matter for my example.""" start="00:16:14.340" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I will explain how it doesn't work easily.""" start="00:16:19.040" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""This is a long-running process which prints something""" start="00:16:22.880" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and it can take up to a few minutes.""" start="00:16:26.520" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And for the whole few minutes I don't see any results,""" start="00:16:29.580" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""the same as with this infinite loop which prints to stdout""" start="00:16:33.360" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""but I don't see anything interactively.""" start="00:16:38.720" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""With `arei`, I can run""" start="00:16:42.200" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""the evaluation of the same expression,""" start="00:16:45.620" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and you will see instantly""" start="00:16:51.440" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""that stdout is presented here in slightly yellowish color.""" start="00:16:54.120" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I can interrupt the evaluation""" start="00:17:00.201" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""if I don't want to wait until it's finished,""" start="00:17:02.921" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and just after that, I can evaluate another value.""" start="00:17:06.040" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""So that's cool.""" start="00:17:15.780" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And let's see one more thing.""" start="00:17:23.360" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""We have an infinite loop and we have some completion here.""" start="00:17:25.960" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And completion still works,""" start="00:17:30.340" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""very nice,""" start="00:17:32.580" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""while the infinite loop is running.""" start="00:17:33.660" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Okay.""" start="00:17:40.260" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""Actually it took me around two months""" start="00:17:42.060" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""of full-time work funded by my own savings,""" start="00:17:44.920" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and you can support and help to the project""" start="00:17:48.040" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""using OpenCollective or by contributing on SourceHut.""" start="00:17:51.600" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""The future steps for the project""" start="00:17:57.020" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""include an experimental workflow where you have""" start="00:17:58.700" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""multiple simultaneous evaluation in different contexts.""" start="00:18:03.675" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""For example, you have Fibers, you have Goblins,""" start="00:18:07.540" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""you have some HTTP server or some other thing,""" start="00:18:11.960" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and you want to run all of them independently""" start="00:18:16.920" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""in slightly isolated sessions,""" start="00:18:22.120" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and you want to have the ability""" start="00:18:25.320" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""to still interact with them.""" start="00:18:29.800" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""For example, if they require standard input""" start="00:18:30.960" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""or something else, you want to be able to provide it.""" start="00:18:33.980" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""You want to see the stderr and stdout""" start="00:18:39.240" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""of those long-running processes and so on.""" start="00:18:42.520" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""The second thing is tree-sitter integration""" start="00:18:46.220" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""for better syntax highlighting, code navigation,""" start="00:18:50.240" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and other features.""" start="00:18:53.400" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""And after that, probably we will do a full-fledged debugger""" start="00:18:56.880" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""so you can jump expressions one by one""" start="00:19:01.400" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and see the results and see some intermediate values""" start="00:19:06.240" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""during the evaluation.""" start="00:19:10.780" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And it's very possible""" start="00:19:13.080" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""because nREPL is a very extensible protocol""" start="00:19:14.480" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and you can implement""" start="00:19:17.080" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""whatever you want on top of it.""" start="00:19:18.200" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""I will answer two probably very frequent questions.""" start="00:19:22.760" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Does it support other Scheme implementations?""" start="00:19:27.080" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""At the moment, it doesn't,""" start="00:19:30.500" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""but the Scheme implementation is not restricted.""" start="00:19:32.280" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""You have a server which is implemented in your language""" start="00:19:36.520" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and you have a client--in our case, `arei`--""" start="00:19:40.640" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""which communicates with this protocol.""" start="00:19:43.975" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""So if you implement nREPL server in a different language,""" start="00:19:48.320" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""it should work with already implemented `arei` client.""" start="00:19:52.360" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""And is it possible to use the same functionality""" start="00:19:58.380" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""in other text editors, for example in VS Code,""" start="00:20:04.080" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Vim, whatever?""" start="00:20:07.000" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""Yes, it's possible and the case is similar here.""" start="00:20:08.680" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""You have already implemented nREPL server""" start="00:20:13.800" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and you can write your own nREPL client""" start="00:20:16.600" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""in a different text editor and it will work.""" start="00:20:19.360" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""I would like to thank the authors and maintainers""" start="00:20:22.121" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and contributors of Guile, Geiser, CIDER, Clojure,""" start="00:20:26.760" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""and Emacs, and all other people""" start="00:20:30.440" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""who are somehow related to the work on those projects""" start="00:20:33.360" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""involved in this talk.""" start="00:20:38.780" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""And I hope the Scheme programming will be enjoyable.""" start="00:20:42.080" video="mainVideo-scheme" id="subtitle"]] +[[!template new="1" text="""If you want to contact me,""" start="00:20:45.880" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""join #tropin IRC channel at libera.chat,""" start="00:20:47.240" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""or drop me a message via email or feediverse""" start="00:20:49.800" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""using `andrew@trop.in` handle.""" start="00:20:53.040" video="mainVideo-scheme" id="subtitle"]] +[[!template text="""I will see you in a bit in Q&A session.""" start="00:20:55.880" video="mainVideo-scheme" id="subtitle"]] + + + +Captioner: sachac + Questions or comments? Please e-mail [emacsconf-org-private@gnu.org](mailto:emacsconf-org-private@gnu.org?subject=Comment%20for%20EmacsConf%202022%20scheme%3A%20Bringing%20joy%20to%20Scheme%20programming) diff --git a/2023/info/scheme-before.md b/2023/info/scheme-before.md index 5a9a7400..a5825f60 100644 --- a/2023/info/scheme-before.md +++ b/2023/info/scheme-before.md @@ -8,12 +8,36 @@ The following image shows where the talk is in the schedule for Sun 2023-12-03. Format: 22-min talk; Q&A: BigBlueButton conference room Etherpad: Discuss on IRC: [#emacsconf-dev](https://chat.emacsconf.org/?join=emacsconf,emacsconf-dev) -Status: Ready to stream +Status: Now playing on the conference livestream
Times in different timezones:
Sunday, Dec 3 2023, ~10:00 AM - 10:20 AM EST (US/Eastern)
which is the same as:
Sunday, Dec 3 2023, ~9:00 AM - 9:20 AM CST (US/Central)
Sunday, Dec 3 2023, ~8:00 AM - 8:20 AM MST (US/Mountain)
Sunday, Dec 3 2023, ~7:00 AM - 7:20 AM PST (US/Pacific)
Sunday, Dec 3 2023, ~3:00 PM - 3:20 PM UTC
Sunday, Dec 3 2023, ~4:00 PM - 4:20 PM CET (Europe/Paris)
Sunday, Dec 3 2023, ~5:00 PM - 5:20 PM EET (Europe/Athens)
Sunday, Dec 3 2023, ~8:30 PM - 8:50 PM IST (Asia/Kolkata)
Sunday, Dec 3 2023, ~11:00 PM - 11:20 PM +08 (Asia/Singapore)
Monday, Dec 4 2023, ~12:00 AM - 12:20 AM JST (Asia/Tokyo)
Find out how to watch and participate
+
[[!template id="chapters" vidid="scheme-mainVideo" data=""" +00:02.120 Introduction +00:23.280 Interactive development +01:18.180 REPL: Read Eval Print Loop +02:53.720 Long-lasting loops +04:07.600 Not interruptible +05:23.160 No protocol +05:51.480 Not scalable +07:25.860 nREPL +09:01.740 Arei, Ares, and how to try +10:34.180 Demo +11:27.640 Continuations +12:32.460 Reading from stdin +13:33.420 Fancy example with continuations +15:13.160 Guix API +17:42.060 Support +17:57.020 Future steps - Multiple simultaneous evaluations in different contexts +18:46.220 Tree-sitter integration +18:56.880 Full-fledged debugger +19:22.760 FAQ - Does it support other Scheme implementations? +19:58.380 Is it possible to use it with other text editors? +20:22.121 Conclusion +20:45.880 Contacts +"""]]
Duration: 21:01 minutes
# Description \ No newline at end of file -- cgit v1.2.3