forked from objectionary/news.eolang.org
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(objectionary#28): Add blog post about probing
feat(objectionary#28): add .idea to gitignore feat(objectionary#28): Add the article about probing mechanism
- Loading branch information
1 parent
c34ca11
commit b12db67
Showing
2 changed files
with
180 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,4 +4,5 @@ _site | |
Gemfile.lock | ||
.jekyll-metadata | ||
_temp/ | ||
.jekyll-cache/ | ||
.jekyll-cache/ | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
--- | ||
layout: post | ||
date: 2023-03-13 | ||
title: "Probing" | ||
author: volodya-lombrozo | ||
--- | ||
|
||
## Overview | ||
|
||
The EO language has a convenient feature that enables the use of objects | ||
without the need to specify their source, location or origin. A developer can | ||
simply print the name of the object and that is all that is required. The | ||
compiler will automatically locate all the requested objects through the | ||
implementation of a new probing feature, which was recently added. In this short | ||
blog, we will attempt to explain how this feature works. Let's take a look at | ||
the following code snippet: | ||
|
||
```eo | ||
[] > app | ||
org.eolang.io.stdout > @ | ||
org.eolang.txt.sprintf | ||
"Magic number is %d" | ||
4815162342 | ||
``` | ||
|
||
As you can see from the code, the purpose of this program is to print the magic | ||
number to the standard output. However, what is `org.eolang.io.stdout` and | ||
`org.eolang.io.stdout` here? They all are objects, right. | ||
Moreover, `org`, `org.eolang` , `org.eolang.io` are objects too. | ||
|
||
But where are they? Is it `org.eolang.io` object that contains `stdout` | ||
attribute, or `org.eolang.io.stdout` is the top-level object itself? | ||
In other words, the compiler needs to distinguish between objects that | ||
are part of other objects (attributes) and those that are top-level objects. | ||
For instance, `org.eolang.io.stdout` is a top-level object, whereas | ||
`org.eolang.io.stdout.length` is an object-attribute of `org.eolang.io.stdout`. | ||
|
||
Hence, the compiler must have the ability to locate all of these objects and | ||
make the process transparent for the developer. This process is called | ||
_probing_. | ||
|
||
## Implementation | ||
|
||
During the compilation of the application from the example above, the compiler | ||
will create a list of all possible objects that the application might require | ||
and add them to the `meta` section. This list ensures that the compiler is aware | ||
of all the necessary objects and will try to locate them as needed: | ||
|
||
```eo | ||
+probe org | ||
+probe org.eolang | ||
+probe org.eolang.io | ||
+probe org.eolang.txt | ||
+probe org.eolang.io.stdout | ||
+probe org.eolang.txt.sprintf | ||
[] > app | ||
org.eolang.io.stdout > @ | ||
org.eolang.txt.sprintf | ||
"Magic number is %d" | ||
4815162342 | ||
``` | ||
|
||
The same is in `XMIR` form: | ||
|
||
```xml | ||
|
||
<metas> | ||
<meta> | ||
<head>probe</head> | ||
<part>Q.org</part> | ||
</meta> | ||
<meta> | ||
<head>probe</head> | ||
<part>Q.org.eolang</part> | ||
</meta> | ||
<meta> | ||
<head>probe</head> | ||
<part>Q.org.eolang.io</part> | ||
</meta> | ||
<meta> | ||
<head>probe</head> | ||
<part>Q.org.eolang.txt</part> | ||
</meta> | ||
<meta> | ||
<head>probe</head> | ||
<part>Q.org.eolang.io.stdout</part> | ||
</meta> | ||
<meta> | ||
<head>probe</head> | ||
<part>Q.org.eolang.txt.sprintf</part> | ||
</meta> | ||
</metas> | ||
``` | ||
|
||
In the EO language, the compiler does not differentiate between top-level | ||
objects and object attributes. As a result, it must check all possible objects | ||
in the Objectionary one by one. If the object exists in the Objectionary, the | ||
compiler will download it and continue with the building process. If the object | ||
does not exist in the Objectionary, the compiler will simply skip it: | ||
|
||
```eo | ||
+probe org # Not found - | ||
+probe org.eolang # Not found - | ||
+probe org.eolang.io # Not found - | ||
+probe org.eolang.txt # Not found - | ||
+probe org.eolang.io.stdout # Found + | ||
+probe org.eolang.txt.sprintf # Found + | ||
``` | ||
|
||
In the example mentioned earlier, the probing process will only locate two | ||
top-level objects in the Objectionary: `org.eolang.io.stdout` and | ||
`org.eolang.txt.sprintf`. | ||
|
||
## Optimizations | ||
|
||
The naive implementation of checking each object in the Objectionary one by one | ||
is obviously not the most efficient in terms of speed and effectiveness. To | ||
speed up the probing process, several improvements have been implemented. These | ||
improvements make the probing process more efficient and accurate, while also | ||
reducing the overall execution time of the compiler. | ||
|
||
### Local objects | ||
|
||
The first and simplest optimization to improve the probing process is to use | ||
local files and cache. This means that not all objects need to be found in the | ||
Objectionary. Some objects may be present locally in the program text or in the | ||
local cache. The compiler will first check these local sources before searching | ||
for the objects in the Objectionary. By utilizing local files and cache, the | ||
probing process becomes faster and more efficient, as the compiler does not need | ||
to spend time searching for objects that are already present locally. | ||
|
||
### Filtering | ||
|
||
Another optimization that was implemented is filtering out certain objects | ||
that are not relevant to the probing process. For example, in the Objectionary, | ||
objects with a package length of less than 3 do not exist, which | ||
means that objects such as `org`, `com`, and `org.eolang` are not valid for | ||
probing. These objects can be filtered out during the probing process, reducing | ||
the number of unnecessary checks and making the process faster and more | ||
efficient. By filtering out irrelevant objects, the compiler can focus on | ||
locating the objects that are actually necessary for the program. | ||
|
||
### Index file | ||
|
||
Checking each object in the Objectionary one by one can also result in a high | ||
number of HTTP requests, which is not ideal in terms of performance. To improve | ||
the speed of the probing process, an index file has been added that contains a | ||
list of all objects in the Objectionary. This index file is downloaded once, and | ||
then used to decrease the overall number of check requests required during the | ||
probing process. The index file can be accessed at | ||
this [link](https://github.com/objectionary/home/blob/gh-pages/objectionary.lst), | ||
and its content appears as follows: | ||
|
||
```txt | ||
objects/org/eolang/bytes.eo | ||
objects/org/eolang/string.eo | ||
objects/org/eolang/seq.eo | ||
objects/org/eolang/as-phi.eo | ||
objects/org/eolang/rust.eo | ||
objects/org/eolang/int.eo | ||
objects/org/eolang/txt/regex.eo | ||
objects/org/eolang/txt/text.eo | ||
objects/org/eolang/txt/sprintf.eo | ||
... | ||
objects/org/eolang/io/stdout.eo | ||
... | ||
objects/org/eolang/txt/sprintf.eo | ||
... | ||
``` | ||
|
||
The index file contains a list of top-level objects that can be used in the | ||
probing. For example, the objects `objects/org/eolang/io/stdout.eo` and | ||
`objects/org/eolang/txt/sprintf.eo` will be used in our code example. The | ||
important thing here is that by using the index file, only one HTTP request is | ||
required to retrieve the file, instead of multiple requests to locate each | ||
object individually in the Objectionary. This results in a faster and more | ||
efficient probing process. |