EO (stands for Elegant Objects or ISO 639-1 code of Esperanto) is an object-oriented programming language. We're aware of popular semi-OOP languages and we don't think they are good enough, including Java, Ruby, C++, Smalltalk, Python, PHP, C#: all of them have something we don't tolerate.
EO is not planning to become a mainstream languageโthis is not what we want. Our main goal is to prove to ourselves that true object-oriented programming is practically possible. Not just in books and abstract examples, but in real code that works. That's why EO is being createdโto put all that "crazy" pure object-oriented ideas into practice and see whether they can work.
EO is based on ๐-calculus (if you want to discuss it, join this Telegram chat: @polystat_org).
Our Twitter tag is #eolang.
These things we don't tolerate:
- types (why?)
- static/class methods or attributes (why?)
- classes (why?)
- implementation inheritance (why?)
- mutability (why?)
- NULL (why?)
- global scope (why?)
- type casting (why?)
- reflection
- scalar types and data primitives
- annotations (why?)
- operators
- traits and mixins (why?)
- flow control statements (
for
,while
,if
, etc) - DSL and syntactic sugar (why?)
There are products that use EO or ๐-calculus (if you want yours to be in the list, submit a pull request):
- objectionary is a repository of EO objects
- polystat is a static analyzer of EO programs
- eo2py is a translator of EO to Python
- try-phi is an online interpreter of ๐-calculus expressions
If you want to cite us, use this BibTeX citation:
@misc{bugayenko2021eolang,
title={EOLANG and phi-calculus},
author={Yegor Bugayenko},
year={2021},
eprint={2111.13384},
archivePrefix={arXiv},
primaryClass={cs.PL}
}
Here is a simple program that gets a year from command line and tells you whether it's leap or not:
+alias org.eolang.io.stdout
+alias org.eolang.txt.sprintf
[args...] > main
[y] > leap
or. > @
and.
eq. (mod. y 4) 0
not. (eq. (mod. y 100) 0)
eq. (mod. y 400) 0
stdout > @
sprintf
"%d is %sa leap year!"
(args.get 0).as-int > year!
if. (leap year:y) "" "not "
In order to compile this program, put it into src/main/eo/main.eo
and then
create a file pom.xml
with this content (it's just a sample):
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.eolang</groupId>
<artifactId>eo-maven-plugin</artifactId>
<version><!-- check Maven Central --></version>
<executions>
<execution>
<goals>
<goal>register</goal>
<goal>assemble</goal>
<goal>transpile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>org.eolang.phi.Main</mainClass>
<arguments>
<argument>main</argument>
<argument>2008</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</project>
Then, you just run mvn clean test
(you will need Maven 3.3+)
and the .eo
file will be parsed to .xml
files, transformed to .java
files,
and then compiled to .class
files. You can see them all in the target
directory.
You will need Java 8+.
More examples are here.
Let's start with a simple EO program:
+alias org.eolang.io.stdout
[] > app
stdout > @
"Hello, world!"
Here we create a new abstract object
named app
, which has got a single attribute named @
. The object attached to the attribute
@
is a copy of the object stdout
with a single argument "Hello, world!"
. The object
stdout
is also abstract.
It can't be used directly, a copy of it has to be created, with a few requirement arguments provided.
This is how a copy of the object stdout
is made:
stdout
"Hello, world!"
The indentation in EO is important, just like in Python. There have to be two spaces in front of the line in order to go to the deeper level of nesting. This code can also be written in a "horizontal" notation:
stdout "Hello, world!"
Moreover, it's possible to use brackets in order to group arguments and avoid
ambiguity. For example, instead of using a plain string "Hello, world!"
we may want to create a copy of the object stdout
with a more complex
argument: a copy of the object sprintf
:
+alias org.eolang.io.stdout
+alias org.eolang.txt.sprintf
[] > app
stdout > @
sprintf
"Hello, %s!"
"Jeffrey"
Here, the object sprintf
is also abstract.
It is being copied with two arguments: "Hello, %s!"
and "Jeffrey"
. This program
can be written using horizontal notation:
+alias org.eolang.io.stdout
+alias org.eolang.txt.sprintf
[] > app
(stdout (sprintf "Hello, %s!" "Jeffrey")) > @
The special attribute @
denotes an object that is being
decorated.
In this example, the object app
decorates the copy of the
object stdout
and through this starts to behave like
the object stdout
: all attributes of stdout
become the
attributes of the app
. The object app
may have its own
attributes. For example, it's possible to define a new abstract object
inside app
and use it to build the output string:
+alias org.eolang.io.stdout
+alias org.eolang.txt.sprintf
[] > app
stdout (msg "Jeffrey") > @
[name] > msg
sprintf "Hello, %s!" name > @
Now, the object app
has two "bound" attributes: @
and msg
. The attribute
msg
has an abstract object attached to it, with a single "free" attribute
name
.
This is how you iterate:
+package sandbox
+alias org.eolang.io.stdout
+alias org.eolang.txt.sprintf
[args...] > app
memory > x
and. > @
x.write 2
while.
x.less 6
[i]
seq > @
stdout
sprintf "%dx%d = %d\n" x x (x.pow 2)
x.write (x.add 1)
This code will print this:
2 x 2 = 4
3 x 3 = 9
4 x 4 = 16
5 x 5 = 25
Got the idea?
The entire process of turning an .eo
program into an executable
binary code constists of a few steps, which must be done
one after another:
-
Parsing. It's done by the
org.eolang.parser.Syntax
class in theeo-parser
module. It takes the source code in a plain text format and parses into XML document, using ANTLR4 and Xembly. The output of the parser you can find in thetarget/eo/parse
directory. -
Optimization. There are a number of XSL transformations that need to be done with the XML document in order to make it ready for compilation. Each transformation has its own
.xsl
file in theeo-parser
directory. The classorg.eolang.parser.Program
is responsible for making XSLT transformations and the entire list of them is stored in theorg.eolang.parser.Pack
class. Some of XLST files are sanity checks (or linters). The output of each transformation you can find in thetarget/eo/optimize
directory. -
Compilation. The class
org.eolang.maven.CompileMojo
in theeo-maven-plugin
module is responsible for putting parsing and optimization steps together and then transforming the XML document into a collection of.java
files. There are a number of transformations that do this, they all exist in.xsl
files. The output of this step you can find in thetarget/generated-sources
directory.
There is also a module called eo-runtime
, which includes both .eo
and .java
code
for most popular and important objects that any of you will need in order
to write even a simple EO program. There are objects like string
, int
, sprintf
,
stdout
, and so on. By the way, you may want to contribute there by creating new objects.
Fork repository, make changes, send us a pull request.
We will review your changes and apply them to the master
branch shortly,
provided they don't violate our quality standards. To avoid frustration,
before sending us your pull request please run full Maven build:
$ ./mvnw clean install -Pqulice
You will need Maven 3.3+ and Java 8+.