Hello and welcome everyone and it was done in 2026. Today we talk about Gile and tooling and
some development practices. So this talk is targeted against newcomers who want to start
with Gile or already experienced people who want to have more fun with Gile. And the goal
is to get in as much fun as possible from programming in Gile language and for this we will
be discussing the different practices and also we will be using some tools which have
to properties. They are reliable and they are interactive and talking about interactive
you not only can interact with them but they also fast. There is some research talking
about the tools that when you interact with something with some program and it replies
under 100 milliseconds it feels like instant response and you feel like engaged. If it takes
a bit more time it feels slagger. If it takes more than one second you already distracted by
but still can keep focus. And above the 10 second you switch into your context and you lost
forever. So we try to be in the first category and 100 milliseconds and sometimes going a bit
above. It's not completely covers all the edge cases and stuff but it will cover 80% of the
goodness that you need to feel comfortable with Gile. The topics for today we will talk about
triple. Most probably famous thing about this is a triple so cool tool for like interactive
development of the stuff and a triple driven development of course. After that we will talk
about organizational stuff, how to structure your code, how to structure your models,
directories and those etc. A bit boring but important part. After that setting up the environment
probably some of you hear a word geeks and I will mention it a few times during the talk.
The next step will be talking about Enriple and what is difference with Reple and why it's
important. A bit of topic of the next talk going beyond Emacs we will touch it lightly and I hope
the next talk will cover it much more deeply and highly interactive development environments
and development workflows and of course demos. How to debug Gile programs and testing
and test driven development. So this is a sneak peek into what will be in the topic and something
about myself. Probably already know me but for people who will be watching the recording,
I am Enriple Trapin, I work on operating systems and programming languages and a lot of free
independent sources of the way including those projects. Geeks home is a staff for managing
your dot files and home environments and three will be using inside our talk for Dema and RG is
going to Linux distribution based on GNU Geeks package manager and we also will use it for Dema.
Suitable testing collaborate is a library for Gile for writing tests and executing Zemony Reple
and in other way and RASGile ID. The primary thing that I personally use for development and
hope after the talk you will use to. Usually when you start programming analysis you can
see that Reple is the only thing that you need. The overall idea, by the way, who is familiar with Reples?
Okay, I won't be explaining into my details so just long-running process that you like
and incrementally modified by sending S expressions to the prompt and immediately getting the response
like the value of the evaluation of the S expression. So it has immediate feedback and it's fun.
I would like to show the Dema but probably all of you so how Reples works so I will skip this part
and we will go to the next part. The Reple questions. When you start on a very simple experimentation
or of course evaluating simple expressions and getting values is fun comfortable fast and all that stuff
but when you build a bigger project it's a bit hard to manipulate on the smallest expressions.
You need files, models, all that structure and you need to switch between your source code and
Reple copies snippets back and forth. Then you need to, for example, get the knowledge
where the function that you using is Reple is defined in your project or in your dependency.
You probably need to construct another expression which will extract this information from runtime,
not very fun anymore. Like to find function definitions to persist results,
got to be a step back and forth, takes a bit of time. We can do better and I will show you
in a few minutes how to do so and managing the library's dependencies and all that stuff.
It's outside of the Reple scope and we will cover it soon as well.
So Reple, quick and easy, not highly but interactive and it's a bit hard to integrate it into
your text editor because like, of this back and forth jumping and even if you try to wrap it
with some APIs, interacting with as to the in-reple, the single synchronous process is a bit
tough and you can see the examples where it fails but won't be diving too much into it.
But when the next time you will be programming in-gile, try to run something, for example,
for evaluation and get some go-to-definition functionality working. If you use a usual
as to the in-reple, it probably will fail. A bit of organizational part.
If you have written in any language, which have models, it's often the case that models
corresponds to the file structure and usually you name the models the following way.
The project, your project name, whatever, you're the main or something like
distinguishing the model from all as the models that possibly exist in the universe.
The category and purpose or some other categorization approach and it corresponds to the file.
It will be important a bit later but for people who come in it's better to know that
it's good to keep these correspondence. The model and file hierarchy.
Also, when you write in-gile, it's quite old language and people used it as a basket,
so you have imperative code and you just load it into repel or whatever and it executes
this code line by line. In modern projects when you have multiple models and you have such a file
which have imperative side effect book code, when it will be loaded by the compiler or interpreter,
it will fire those side effects and this is what we don't want when we have to be
project the random side effects happening on the loading of the models. That is why every time
when you define a model, to make only top level definitions of the functions, no side effect
full top level code. What I mean? For example, if you write to the file, if you have something
that writes to the file, it should be wrapped into the function. So before fighting the side effect,
you need to call this function. You can call it from CLI, from Ripple, from whatever,
but try not to use top level side effect full forms in your code. It will save you a lot of time
and it will be much fun to work with. And the last thing that I recommend to make a
correspondence between your usual models and models with tests, just by adding a test prefix
at the end. And that's basically it about basic organizational structure after that. You have your source
code, some way in the directory and you structure the models well, and you put your code well.
Now you have another level of directory, that grows the code by pullpows. For example,
your application wraps some secret. So it's better to create folder with C headers and
wrappers and your folder with schema source code, which uses those wrappers.
Or you have a back end part and front end part, or you have like something complimented in
gileskim and something implemented in gileskud. It's better to keep in different directories.
So later you can, for example, using load pass variable, specify where to look for the
related source code for a particular part of your project. And we will see the example of this
structure just in a bit. It's still a boring part, and I hope you get bored enough because
like later we will have a bit more fun, but it's necessary to talk because it takes a lot of
time from people who starting to work with them. And the last recommendations that I have
to use a few top level directories. First one is ENV for storing all the information,
scripts, and source code related to the environment, to how to set up the environment.
Source code is a primary directorie way. You store your project sources. Test is a separate
directorie from primary sources, because for example, when you want to release a project,
you would like to be sure that nothing from your tests leaks into your release. Because you
had like some draft or some incomplete functions or maybe some dirty implementations and helpers,
you want to be sure that nothing in the release. That's why we separate them in completely
different directorie. And DEF is a directorie for experiments, drafts, and all that seems.
Okay, let's see how it can work. I will do a less.
Okay. So this is a top level of some project, and you can see those directories I mentioned.
And now let's see how the three looks like. You can see this a DEF directorie. Inside the DEF
directorie, I have a directorie which says Gail. That means it's only a Gail source code.
If I had a hood source code or C source code, it will be like a separate directorie nearby.
And here you can see a lot of experienced mutations that I had, some demo files, and all other stuff.
The end directorie contains quite involved structure, and I will explain it in a minute.
But it contains information of how to set up the environment with geeks.
And the primary source code for my project, which structures, as I mentioned before,
a name of the project like category and purpose or whatever, particularization where you use.
And tests. You can see the test like mimics the structure of the primary source code.
But in the model names, I have a minus test for perfect extent, which helps if you keep this
convention, which helps to do functions like jumping to the corresponding model with tests.
And loading tests for the current model and all that stuff. Just a simple convention, but
simplifies a lot of things. Okay. Now the load pass, who knows what load passes?
Okay. Half of the people, very good. This is basically a place where your compiler looks up for the
code. And one of the tasks that you need to do to work on a guide project or many other languages,
as well, is to set up load pass correctly. So it can find your source code. It can find dependencies
of your source code like libraries, compilers, and all that things that you will use.
And I have quite extensive article. You can look it up later, but what else load passes allows us to do?
It allows us to create a profiles, profiles for different needs. Sometimes we run and compile
our source code for a list propose. Sometimes we want to run tests on CI. So we need not only our
source code, but also our tests to be available for the compiler. And sometimes we need for
development propose. So we need our tests, we need additional drafts, we need maybe some additional
dependencies, which allows spying on our code and doing some debugging. So this mechanism
allows us to create a profiles for different tasks at hand. And how basically do it in my project?
I will show you right here. We have make files. And inside this make files, you can see that
I specify different load passes for different proposals. For example, for dev, guide process,
I use my source code, primary source code tests, and my dev with draft. But for running tests,
I don't need those drafts. So I have on the test here. And for the list, I use only my primary source code.
And I'm sure that nothing from my dev experiments and tests will leak into the final
list, which is quite, quite handy. Okay, the question. You probably remember in the demos that
I didn't show that I run the guide. And it spawns a ripple. And the question is where this guide
comes from? The answer is where, no, which, which guide? The answer is simple from some strange
place. Who installed it? How installed it? What version? What dependencies? Who knows? The only
Richard Stoman maybe, not sure. It's better to control your environment. And all the dependencies
that you have for a project. So we need a tool for this. It's not sponsored by Geeks, but unfortunately,
unfortunately, unfortunately, I don't know a better option so far to do so, so we need to use Geeks.
There's one important thing to note that installing Geeks and doing initial Geeks pool can be
a bit slow. And like, I like it some time in advance if you want to use Geeks for managing
your guide project. But when you set it up, it's extremely reliable. I have projects that, like,
a few years old, I come back to them and they work perfectly without any issues because they're
frozen in time with Geeks and it capability for time traveling. Oops, let's go to the next slide.
A bit of good best practices. Good best practices. So how basically
things works? Probably I should start from this slide. We installed Geeks somehow. Imagine,
imagine, we could do so. After that, we need to use two things. The Geeks shell and Geeks time machine.
Geeks shell allow us to install a guide. And for example, a guide, a QR code. It's sponsored
shell. You can see that prompt is a different right now. And it has additional character in it.
And if I run a guide variable and inside this guide variable, we'll do use models QR code.
It will work. But if I run a guide outside of this shell and we'll do the same thing, use models
QR code. It will fail. No code for model and QR code. So now we can create a shell
and the environment where the guide and the dependencies are available and they have some version.
Which versions they have? I don't know because the Geeks comes from some random place and it has
a random version. And the packages it installs will be of random version. So to be sure that we
use exact versions of a guide and libraries, we will do another trick. We will use Geeks time machine
and specify this long pass to channel system file. I will show what inside it. And we create the same
shell and voila nothing works. Geeks time machine, minus C blah blah blah, minus minus shell,
shell, and we have another shell. But right now I know exactly which version of
use and which version of guide QR code I use. That's because we used time machine and specified
channels SM where I have an exact commit of Geeks I use. So what we did? We pinned it down. We used
exact version of Geeks. We instantiate that exact version of Geeks and after that we created the
environment. So treat this process as two step process. We have some Geeks from some Geeks we create
an exact version of Geeks and this exact version of Geeks create the exact environment which will
be reproducible across different installations, people and servers or whatever. And another recommendation
treat Geeks as a guide library and make it respect long passes. You will use it if you do any
Geeks related stuff like managing your channels, configurations, and whatever.
Okay, that was fast. Okay, very quick to the demo. The Enreple stuff.
Enreple is not a rebel. It's a protocol which allows to communicate with the guide process. I synchronously
and do a lot of integrations and cool goodies. Unfortunately, that I didn't watch at the time.
But let's do some demo. I have a lot of them and they are fun. But we will do something very simple.
You know, this is Emacs and we can spawn a Gile Enreple server connected from Emacs
we did it just like this and start the video in random expressions. You see, we will let this play
it printed high to us to the out and the return and specified value. They have different colors,
so you can distinguish it. If we have a few multiple values return, you will see, you will see them here.
Now, for example, you know that you have a call with escape continuation function and you see there's
no completion for it. We need to export some model or import. I don't remember which way we go.
And now you see escape continuation, completion appeared. Cool. Now let's run infinite loop.
And while this infinite loop running, we want our completion to work again and it still works.
Very cool. In some other places it won't work. And we execute the infinite loop,
but actually we didn't want to continue with it as a stuff. Let's interrupt this infinite loop.
So good, so far. Anybody hear about continuations? Cool. It's very, very tricky
computer science stuff, but what it allows to do. Like inside this infinite loop,
in an infinite loop, I save a current continuation and this is things that I can resume from
interrupting our infinite loop. And you see there's a call to quant, quant is a saved
continuation. We can evaluate, oops, the value you see is a continuation is a return.
And we can run this continuation again. And if you didn't notice, it continued this infinite loop
from the point it stopped before. You see, we was at this place and we started again from this place.
What else? We can call the continuation again with a different value, which is a read number.
And at the bottom of the screen you see a prompt. It asks for the value from SDN. And I can input
some number into it. And you see, it continued this infinite loop, but started with much larger number.
And now, we will go to the next demo. Next demo is related to stack trace. So one of the big
pains in guide development is debugging. And when you get exception, it's hard to understand
where the things went wrong. The reasons I explained in the article actually useful
stack traces that you can find in the internet. But let's imagine that instead of the number we
gave a string or something invalid. And you can see that I got an exception and stack trace
on the right. And I can jump around and I immediately jumped to the place where it failed. And it says
that I is false instead of some number. So somewhere here in string to number
converted our value from readline into false. This probably because we used a string instead of
a number. So we found out the problem and we can restart the loop and use number next time.
But maybe it's not that impressive. The impressive thing happens when you have a huge project
of, I don't know, thousands of the length. And this is my personal configuration which is connected
to the nulline distribution. And this is a problem in it. Let's try to build it.
And you see something that's not very helpful. From this error message, it hard to understand what
is going on. But if we run areas and reports over, connect to it and try to evaluate the
configuration, you will get a very obvious stack trace with which says, expecting pair, but got a string.
A pair is actually a list in in scheme. So it's expected a list not a pair, but whatever.
And you can jump through the stack trace and SSH key, question mark failed. And it failed inside
feature a groupage. And here I see that SSH key is a list of one string, a string, but it should
be a list of lists of string. And after that fixed, I can evaluate the model and it evaluated
correctly. And I restart the rebuild of my home environment and it will work perfectly. And in
another small thing that I will show you in a moment. This is IMAX. I know that not everyone
uses it. And like it's understandable. The good thing that our ID consists of two parts,
areas part, which is an variable server and array part, which is a client. And here like a few
hours ago, Ilia the fellow hacker sent me a video. He opened his NLVM and used a generic and
repell client and connected two areas back end. And he get all the goodies of ID inside his NLVM as well.
So you can see, he can evaluate arbitrary expression and get immediate results. And it all
works through the array that we implemented for our ID. Okay. And on this wonderful note, let me find
my presentation. Oops, sorry. Here, I will jump to the end. I will say that I like teaching
a lot of teaching computer science and building to tackle a hard problems. And those tools I mentioned
today make it actually fun. And I hope it will make some fun for you.
I think we have time for one question. One question, please. Only one. So cool, talks. No questions.
Okay. I did. Yeah, okay. This is a step debugger in NLVM. We looked at it more over,
we did some work during the internship this year with NLVM and Nicolas Graves. And made a proof
of concept of debugger for areas. It works. It has like a relation in a point of failure where
the exception happened. And we also had a very bare bond proof of concept of step debugger as well.
It's in development, but maybe someday you will see it. Okay. Thank you very much.