WEBVTT

00:00.000 --> 00:17.200
Hello and welcome everyone and it was done in 2026. Today we talk about Gile and tooling and

00:17.200 --> 00:25.240
some development practices. So this talk is targeted against newcomers who want to start

00:25.240 --> 00:32.640
with Gile or already experienced people who want to have more fun with Gile. And the goal

00:32.640 --> 00:38.120
is to get in as much fun as possible from programming in Gile language and for this we will

00:38.120 --> 00:45.560
be discussing the different practices and also we will be using some tools which have

00:45.560 --> 00:52.080
to properties. They are reliable and they are interactive and talking about interactive

00:52.080 --> 00:57.200
you not only can interact with them but they also fast. There is some research talking

00:57.200 --> 01:04.080
about the tools that when you interact with something with some program and it replies

01:04.080 --> 01:10.400
under 100 milliseconds it feels like instant response and you feel like engaged. If it takes

01:10.400 --> 01:17.120
a bit more time it feels slagger. If it takes more than one second you already distracted by

01:17.120 --> 01:24.080
but still can keep focus. And above the 10 second you switch into your context and you lost

01:24.080 --> 01:30.560
forever. So we try to be in the first category and 100 milliseconds and sometimes going a bit

01:30.560 --> 01:38.240
above. It's not completely covers all the edge cases and stuff but it will cover 80% of the

01:38.240 --> 01:46.720
goodness that you need to feel comfortable with Gile. The topics for today we will talk about

01:46.720 --> 01:54.240
triple. Most probably famous thing about this is a triple so cool tool for like interactive

01:54.240 --> 02:00.240
development of the stuff and a triple driven development of course. After that we will talk

02:00.240 --> 02:05.120
about organizational stuff, how to structure your code, how to structure your models,

02:05.120 --> 02:12.080
directories and those etc. A bit boring but important part. After that setting up the environment

02:12.160 --> 02:17.840
probably some of you hear a word geeks and I will mention it a few times during the talk.

02:19.120 --> 02:25.440
The next step will be talking about Enriple and what is difference with Reple and why it's

02:25.440 --> 02:33.360
important. A bit of topic of the next talk going beyond Emacs we will touch it lightly and I hope

02:33.360 --> 02:41.120
the next talk will cover it much more deeply and highly interactive development environments

02:41.680 --> 02:47.520
and development workflows and of course demos. How to debug Gile programs and testing

02:47.520 --> 02:54.560
and test driven development. So this is a sneak peek into what will be in the topic and something

02:54.560 --> 02:59.680
about myself. Probably already know me but for people who will be watching the recording,

02:59.680 --> 03:04.000
I am Enriple Trapin, I work on operating systems and programming languages and a lot of free

03:04.000 --> 03:09.120
independent sources of the way including those projects. Geeks home is a staff for managing

03:09.120 --> 03:17.440
your dot files and home environments and three will be using inside our talk for Dema and RG is

03:17.440 --> 03:24.000
going to Linux distribution based on GNU Geeks package manager and we also will use it for Dema.

03:24.720 --> 03:30.160
Suitable testing collaborate is a library for Gile for writing tests and executing Zemony Reple

03:30.160 --> 03:38.560
and in other way and RASGile ID. The primary thing that I personally use for development and

03:38.560 --> 03:47.040
hope after the talk you will use to. Usually when you start programming analysis you can

03:47.040 --> 03:53.600
see that Reple is the only thing that you need. The overall idea, by the way, who is familiar with Reples?

03:56.000 --> 04:02.320
Okay, I won't be explaining into my details so just long-running process that you like

04:02.320 --> 04:08.560
and incrementally modified by sending S expressions to the prompt and immediately getting the response

04:09.600 --> 04:16.000
like the value of the evaluation of the S expression. So it has immediate feedback and it's fun.

04:16.960 --> 04:23.680
I would like to show the Dema but probably all of you so how Reples works so I will skip this part

04:23.680 --> 04:31.120
and we will go to the next part. The Reple questions. When you start on a very simple experimentation

04:31.200 --> 04:36.800
or of course evaluating simple expressions and getting values is fun comfortable fast and all that stuff

04:36.800 --> 04:42.880
but when you build a bigger project it's a bit hard to manipulate on the smallest expressions.

04:42.880 --> 04:50.080
You need files, models, all that structure and you need to switch between your source code and

04:50.080 --> 04:58.080
Reple copies snippets back and forth. Then you need to, for example, get the knowledge

04:58.080 --> 05:03.200
where the function that you using is Reple is defined in your project or in your dependency.

05:03.200 --> 05:08.080
You probably need to construct another expression which will extract this information from runtime,

05:08.080 --> 05:14.640
not very fun anymore. Like to find function definitions to persist results,

05:14.640 --> 05:19.920
got to be a step back and forth, takes a bit of time. We can do better and I will show you

05:19.920 --> 05:26.080
in a few minutes how to do so and managing the library's dependencies and all that stuff.

05:26.080 --> 05:30.560
It's outside of the Reple scope and we will cover it soon as well.

05:32.240 --> 05:39.440
So Reple, quick and easy, not highly but interactive and it's a bit hard to integrate it into

05:39.440 --> 05:46.080
your text editor because like, of this back and forth jumping and even if you try to wrap it

05:46.080 --> 05:52.480
with some APIs, interacting with as to the in-reple, the single synchronous process is a bit

05:52.480 --> 05:58.160
tough and you can see the examples where it fails but won't be diving too much into it.

05:58.160 --> 06:06.560
But when the next time you will be programming in-gile, try to run something, for example,

06:07.840 --> 06:14.400
for evaluation and get some go-to-definition functionality working. If you use a usual

06:14.480 --> 06:21.360
as to the in-reple, it probably will fail. A bit of organizational part.

06:27.360 --> 06:32.960
If you have written in any language, which have models, it's often the case that models

06:32.960 --> 06:40.160
corresponds to the file structure and usually you name the models the following way.

06:40.960 --> 06:46.000
The project, your project name, whatever, you're the main or something like

06:46.000 --> 06:51.200
distinguishing the model from all as the models that possibly exist in the universe.

06:51.760 --> 06:59.600
The category and purpose or some other categorization approach and it corresponds to the file.

06:59.600 --> 07:05.600
It will be important a bit later but for people who come in it's better to know that

07:05.760 --> 07:12.160
it's good to keep these correspondence. The model and file hierarchy.

07:13.440 --> 07:20.400
Also, when you write in-gile, it's quite old language and people used it as a basket,

07:20.400 --> 07:27.680
so you have imperative code and you just load it into repel or whatever and it executes

07:27.680 --> 07:33.360
this code line by line. In modern projects when you have multiple models and you have such a file

07:33.440 --> 07:39.680
which have imperative side effect book code, when it will be loaded by the compiler or interpreter,

07:40.560 --> 07:47.120
it will fire those side effects and this is what we don't want when we have to be

07:47.120 --> 07:53.920
project the random side effects happening on the loading of the models. That is why every time

07:53.920 --> 08:00.800
when you define a model, to make only top level definitions of the functions, no side effect

08:00.800 --> 08:08.720
full top level code. What I mean? For example, if you write to the file, if you have something

08:08.720 --> 08:14.080
that writes to the file, it should be wrapped into the function. So before fighting the side effect,

08:14.080 --> 08:18.240
you need to call this function. You can call it from CLI, from Ripple, from whatever,

08:18.240 --> 08:24.800
but try not to use top level side effect full forms in your code. It will save you a lot of time

08:25.760 --> 08:31.920
and it will be much fun to work with. And the last thing that I recommend to make a

08:31.920 --> 08:38.960
correspondence between your usual models and models with tests, just by adding a test prefix

08:38.960 --> 08:48.960
at the end. And that's basically it about basic organizational structure after that. You have your source

08:48.960 --> 08:53.680
code, some way in the directory and you structure the models well, and you put your code well.

08:54.720 --> 09:01.920
Now you have another level of directory, that grows the code by pullpows. For example,

09:01.920 --> 09:08.960
your application wraps some secret. So it's better to create folder with C headers and

09:08.960 --> 09:15.680
wrappers and your folder with schema source code, which uses those wrappers.

09:16.560 --> 09:21.280
Or you have a back end part and front end part, or you have like something complimented in

09:21.280 --> 09:26.320
gileskim and something implemented in gileskud. It's better to keep in different directories.

09:27.440 --> 09:35.680
So later you can, for example, using load pass variable, specify where to look for the

09:35.680 --> 09:43.600
related source code for a particular part of your project. And we will see the example of this

09:43.680 --> 09:50.640
structure just in a bit. It's still a boring part, and I hope you get bored enough because

09:50.640 --> 09:56.800
like later we will have a bit more fun, but it's necessary to talk because it takes a lot of

09:56.800 --> 10:01.600
time from people who starting to work with them. And the last recommendations that I have

10:02.320 --> 10:08.800
to use a few top level directories. First one is ENV for storing all the information,

10:08.800 --> 10:15.520
scripts, and source code related to the environment, to how to set up the environment.

10:15.520 --> 10:22.960
Source code is a primary directorie way. You store your project sources. Test is a separate

10:22.960 --> 10:28.800
directorie from primary sources, because for example, when you want to release a project,

10:28.800 --> 10:37.120
you would like to be sure that nothing from your tests leaks into your release. Because you

10:37.120 --> 10:43.200
had like some draft or some incomplete functions or maybe some dirty implementations and helpers,

10:43.200 --> 10:48.640
you want to be sure that nothing in the release. That's why we separate them in completely

10:48.640 --> 10:54.240
different directorie. And DEF is a directorie for experiments, drafts, and all that seems.

10:55.120 --> 11:01.440
Okay, let's see how it can work. I will do a less.

11:01.520 --> 11:13.520
Okay. So this is a top level of some project, and you can see those directories I mentioned.

11:13.520 --> 11:21.760
And now let's see how the three looks like. You can see this a DEF directorie. Inside the DEF

11:21.760 --> 11:27.600
directorie, I have a directorie which says Gail. That means it's only a Gail source code.

11:27.600 --> 11:33.760
If I had a hood source code or C source code, it will be like a separate directorie nearby.

11:34.480 --> 11:41.360
And here you can see a lot of experienced mutations that I had, some demo files, and all other stuff.

11:42.400 --> 11:48.960
The end directorie contains quite involved structure, and I will explain it in a minute.

11:49.520 --> 11:53.360
But it contains information of how to set up the environment with geeks.

11:54.320 --> 12:01.840
And the primary source code for my project, which structures, as I mentioned before,

12:01.840 --> 12:07.680
a name of the project like category and purpose or whatever, particularization where you use.

12:10.000 --> 12:17.360
And tests. You can see the test like mimics the structure of the primary source code.

12:17.360 --> 12:24.800
But in the model names, I have a minus test for perfect extent, which helps if you keep this

12:24.800 --> 12:29.680
convention, which helps to do functions like jumping to the corresponding model with tests.

12:30.640 --> 12:36.000
And loading tests for the current model and all that stuff. Just a simple convention, but

12:36.000 --> 12:45.120
simplifies a lot of things. Okay. Now the load pass, who knows what load passes?

12:47.440 --> 12:54.880
Okay. Half of the people, very good. This is basically a place where your compiler looks up for the

12:54.880 --> 13:04.640
code. And one of the tasks that you need to do to work on a guide project or many other languages,

13:04.640 --> 13:10.560
as well, is to set up load pass correctly. So it can find your source code. It can find dependencies

13:10.560 --> 13:16.240
of your source code like libraries, compilers, and all that things that you will use.

13:17.040 --> 13:24.560
And I have quite extensive article. You can look it up later, but what else load passes allows us to do?

13:30.240 --> 13:36.880
It allows us to create a profiles, profiles for different needs. Sometimes we run and compile

13:36.880 --> 13:44.160
our source code for a list propose. Sometimes we want to run tests on CI. So we need not only our

13:44.160 --> 13:51.040
source code, but also our tests to be available for the compiler. And sometimes we need for

13:51.040 --> 13:56.880
development propose. So we need our tests, we need additional drafts, we need maybe some additional

13:56.880 --> 14:04.080
dependencies, which allows spying on our code and doing some debugging. So this mechanism

14:04.080 --> 14:13.520
allows us to create a profiles for different tasks at hand. And how basically do it in my project?

14:16.080 --> 14:24.960
I will show you right here. We have make files. And inside this make files, you can see that

14:24.960 --> 14:33.680
I specify different load passes for different proposals. For example, for dev, guide process,

14:33.680 --> 14:41.200
I use my source code, primary source code tests, and my dev with draft. But for running tests,

14:41.200 --> 14:47.520
I don't need those drafts. So I have on the test here. And for the list, I use only my primary source code.

14:48.400 --> 14:55.760
And I'm sure that nothing from my dev experiments and tests will leak into the final

14:55.760 --> 15:03.120
list, which is quite, quite handy. Okay, the question. You probably remember in the demos that

15:03.120 --> 15:11.920
I didn't show that I run the guide. And it spawns a ripple. And the question is where this guide

15:12.000 --> 15:23.520
comes from? The answer is where, no, which, which guide? The answer is simple from some strange

15:23.520 --> 15:30.800
place. Who installed it? How installed it? What version? What dependencies? Who knows? The only

15:32.560 --> 15:41.200
Richard Stoman maybe, not sure. It's better to control your environment. And all the dependencies

15:41.280 --> 15:55.040
that you have for a project. So we need a tool for this. It's not sponsored by Geeks, but unfortunately,

15:55.040 --> 16:02.160
unfortunately, unfortunately, I don't know a better option so far to do so, so we need to use Geeks.

16:02.160 --> 16:12.640
There's one important thing to note that installing Geeks and doing initial Geeks pool can be

16:12.640 --> 16:19.200
a bit slow. And like, I like it some time in advance if you want to use Geeks for managing

16:19.200 --> 16:26.160
your guide project. But when you set it up, it's extremely reliable. I have projects that, like,

16:26.240 --> 16:32.640
a few years old, I come back to them and they work perfectly without any issues because they're

16:32.640 --> 16:43.200
frozen in time with Geeks and it capability for time traveling. Oops, let's go to the next slide.

16:43.200 --> 16:54.000
A bit of good best practices. Good best practices. So how basically

16:54.960 --> 17:02.000
things works? Probably I should start from this slide. We installed Geeks somehow. Imagine,

17:02.000 --> 17:08.080
imagine, we could do so. After that, we need to use two things. The Geeks shell and Geeks time machine.

17:09.360 --> 17:17.520
Geeks shell allow us to install a guide. And for example, a guide, a QR code. It's sponsored

17:17.520 --> 17:23.600
shell. You can see that prompt is a different right now. And it has additional character in it.

17:23.600 --> 17:30.000
And if I run a guide variable and inside this guide variable, we'll do use models QR code.

17:32.800 --> 17:41.040
It will work. But if I run a guide outside of this shell and we'll do the same thing, use models

17:41.840 --> 17:48.960
QR code. It will fail. No code for model and QR code. So now we can create a shell

17:48.960 --> 17:55.520
and the environment where the guide and the dependencies are available and they have some version.

17:55.520 --> 18:03.360
Which versions they have? I don't know because the Geeks comes from some random place and it has

18:03.360 --> 18:11.040
a random version. And the packages it installs will be of random version. So to be sure that we

18:11.040 --> 18:20.080
use exact versions of a guide and libraries, we will do another trick. We will use Geeks time machine

18:20.080 --> 18:29.760
and specify this long pass to channel system file. I will show what inside it. And we create the same

18:29.760 --> 18:40.000
shell and voila nothing works. Geeks time machine, minus C blah blah blah, minus minus shell,

18:40.960 --> 19:01.680
shell, and we have another shell. But right now I know exactly which version of

19:02.000 --> 19:08.720
use and which version of guide QR code I use. That's because we used time machine and specified

19:08.720 --> 19:20.240
channels SM where I have an exact commit of Geeks I use. So what we did? We pinned it down. We used

19:20.240 --> 19:26.800
exact version of Geeks. We instantiate that exact version of Geeks and after that we created the

19:26.800 --> 19:33.920
environment. So treat this process as two step process. We have some Geeks from some Geeks we create

19:33.920 --> 19:39.120
an exact version of Geeks and this exact version of Geeks create the exact environment which will

19:39.120 --> 19:46.480
be reproducible across different installations, people and servers or whatever. And another recommendation

19:47.280 --> 19:56.640
treat Geeks as a guide library and make it respect long passes. You will use it if you do any

19:57.120 --> 20:00.800
Geeks related stuff like managing your channels, configurations, and whatever.

20:04.000 --> 20:12.800
Okay, that was fast. Okay, very quick to the demo. The Enreple stuff.

20:13.520 --> 20:19.360
Enreple is not a rebel. It's a protocol which allows to communicate with the guide process. I synchronously

20:19.360 --> 20:25.760
and do a lot of integrations and cool goodies. Unfortunately, that I didn't watch at the time.

20:26.400 --> 20:38.320
But let's do some demo. I have a lot of them and they are fun. But we will do something very simple.

20:38.400 --> 20:56.880
You know, this is Emacs and we can spawn a Gile Enreple server connected from Emacs

20:56.880 --> 21:04.480
we did it just like this and start the video in random expressions. You see, we will let this play

21:05.120 --> 21:10.080
it printed high to us to the out and the return and specified value. They have different colors,

21:10.080 --> 21:18.320
so you can distinguish it. If we have a few multiple values return, you will see, you will see them here.

21:19.120 --> 21:27.600
Now, for example, you know that you have a call with escape continuation function and you see there's

21:27.760 --> 21:38.240
no completion for it. We need to export some model or import. I don't remember which way we go.

21:39.040 --> 21:48.480
And now you see escape continuation, completion appeared. Cool. Now let's run infinite loop.

21:49.040 --> 21:56.320
And while this infinite loop running, we want our completion to work again and it still works.

21:56.320 --> 22:02.880
Very cool. In some other places it won't work. And we execute the infinite loop,

22:02.880 --> 22:09.280
but actually we didn't want to continue with it as a stuff. Let's interrupt this infinite loop.

22:10.880 --> 22:18.640
So good, so far. Anybody hear about continuations? Cool. It's very, very tricky

22:18.640 --> 22:27.040
computer science stuff, but what it allows to do. Like inside this infinite loop,

22:27.040 --> 22:33.200
in an infinite loop, I save a current continuation and this is things that I can resume from

22:34.400 --> 22:42.400
interrupting our infinite loop. And you see there's a call to quant, quant is a saved

22:42.480 --> 22:48.320
continuation. We can evaluate, oops, the value you see is a continuation is a return.

22:48.320 --> 22:56.560
And we can run this continuation again. And if you didn't notice, it continued this infinite loop

22:56.560 --> 23:04.320
from the point it stopped before. You see, we was at this place and we started again from this place.

23:05.280 --> 23:13.520
What else? We can call the continuation again with a different value, which is a read number.

23:13.520 --> 23:21.120
And at the bottom of the screen you see a prompt. It asks for the value from SDN. And I can input

23:21.120 --> 23:28.080
some number into it. And you see, it continued this infinite loop, but started with much larger number.

23:28.960 --> 23:34.480
And now, we will go to the next demo. Next demo is related to stack trace. So one of the big

23:34.480 --> 23:42.960
pains in guide development is debugging. And when you get exception, it's hard to understand

23:42.960 --> 23:48.960
where the things went wrong. The reasons I explained in the article actually useful

23:49.040 --> 23:54.640
stack traces that you can find in the internet. But let's imagine that instead of the number we

23:57.680 --> 24:03.920
gave a string or something invalid. And you can see that I got an exception and stack trace

24:03.920 --> 24:12.640
on the right. And I can jump around and I immediately jumped to the place where it failed. And it says

24:12.640 --> 24:20.800
that I is false instead of some number. So somewhere here in string to number

24:22.400 --> 24:29.920
converted our value from readline into false. This probably because we used a string instead of

24:30.800 --> 24:36.320
a number. So we found out the problem and we can restart the loop and use number next time.

24:36.960 --> 24:43.680
But maybe it's not that impressive. The impressive thing happens when you have a huge project

24:43.680 --> 24:49.760
of, I don't know, thousands of the length. And this is my personal configuration which is connected

24:49.760 --> 24:58.320
to the nulline distribution. And this is a problem in it. Let's try to build it.

25:07.200 --> 25:14.640
And you see something that's not very helpful. From this error message, it hard to understand what

25:14.640 --> 25:24.560
is going on. But if we run areas and reports over, connect to it and try to evaluate the

25:24.560 --> 25:32.320
configuration, you will get a very obvious stack trace with which says, expecting pair, but got a string.

25:32.960 --> 25:42.560
A pair is actually a list in in scheme. So it's expected a list not a pair, but whatever.

25:42.560 --> 25:51.440
And you can jump through the stack trace and SSH key, question mark failed. And it failed inside

25:51.520 --> 26:01.680
feature a groupage. And here I see that SSH key is a list of one string, a string, but it should

26:01.680 --> 26:08.880
be a list of lists of string. And after that fixed, I can evaluate the model and it evaluated

26:09.920 --> 26:18.000
correctly. And I restart the rebuild of my home environment and it will work perfectly. And in

26:18.000 --> 26:26.560
another small thing that I will show you in a moment. This is IMAX. I know that not everyone

26:26.560 --> 26:36.720
uses it. And like it's understandable. The good thing that our ID consists of two parts,

26:36.720 --> 26:43.840
areas part, which is an variable server and array part, which is a client. And here like a few

26:44.240 --> 26:54.320
hours ago, Ilia the fellow hacker sent me a video. He opened his NLVM and used a generic and

26:54.320 --> 27:05.360
repell client and connected two areas back end. And he get all the goodies of ID inside his NLVM as well.

27:05.920 --> 27:15.040
So you can see, he can evaluate arbitrary expression and get immediate results. And it all

27:15.040 --> 27:23.840
works through the array that we implemented for our ID. Okay. And on this wonderful note, let me find

27:23.840 --> 27:32.000
my presentation. Oops, sorry. Here, I will jump to the end. I will say that I like teaching

27:32.080 --> 27:38.640
a lot of teaching computer science and building to tackle a hard problems. And those tools I mentioned

27:38.640 --> 27:43.840
today make it actually fun. And I hope it will make some fun for you.

27:43.840 --> 28:10.720
I think we have time for one question. One question, please. Only one. So cool, talks. No questions.

28:10.720 --> 28:34.320
Okay. I did. Yeah, okay. This is a step debugger in NLVM. We looked at it more over,

28:34.320 --> 28:43.360
we did some work during the internship this year with NLVM and Nicolas Graves. And made a proof

28:43.360 --> 28:53.680
of concept of debugger for areas. It works. It has like a relation in a point of failure where

28:53.680 --> 29:01.280
the exception happened. And we also had a very bare bond proof of concept of step debugger as well.

29:01.280 --> 29:07.440
It's in development, but maybe someday you will see it. Okay. Thank you very much.

