Skip to content

EOLANG, an Experimental Pure Object-Oriented Programming Language Based on πœ‘-calculus

License

Notifications You must be signed in to change notification settings

objectionary/eo

Repository files navigation

logo

EO principles respected here DevOps By Rultor.com We recommend IntelliJ IDEA

mvn-linux PDD status Maintainability Maven Central codecov Lines-of-Code Hits-of-Code License FOSSA Status Codacy Badge Known Vulnerabilities Code Smells

EO (stands for Elegant Objects or ISO 639-1 code of Esperanto) is an object-oriented programming language based on πœ‘-calculus. 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:

  • types (why?)
  • static/class methods or attributes (why?)
  • classes (why?)
  • implementation inheritance (why?)
  • mutability (why? and why not?)
  • NULL (why?)
  • global scope (why?)
  • type casting (why?)
  • reflection (why?)
  • scalar types and data primitives
  • annotations (why?)
  • operators
  • traits and mixins (why?)
  • flow control statements (for, while, if, etc)
  • syntactic sugar (why?)

Quick Start

First, install Java SE, npm. Then, you install eoc:

npm install -g [email protected]

Then, start with a simple EO program in the app.eo file:

# Just prints hello.
[args] > app
  QQ.io.stdout > @
    "Hello, world!\n"

Compile it like this (may take up to a minute or so):

eoc --easy link

Then, run it:

eoc --easy --alone dataize app

You should see "Hello, world!" printed.

Simple Tutorial

In the example above, 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:

QQ.io.stdout
  "Hello, world!\n"

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:

QQ.io.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:

# Says hello to Jeff.
[] > app
  QQ.io.stdout > @
    QQ.txt.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

# Also says hello to Jeff.
[] > 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:

# Says hello to Jeff.
[] > app
  QQ.io.stdout (msg "Jeffrey") > @
  [name] > msg
    QQ.txt.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:

# Multiplication table.
[args] > app
  malloc.for > @
    0
    [x] >>
      seq > @
        *
          x.put 2
          while
            x.as-number.lt 6 > [i]
            [i] >>
              seq > @
                *
                  QQ.io.stdout
                    QQ.txt.sprintf
                      "%d x %d = %d\n"
                      *
                        ^.x
                        ^.x
                        ^.x.as-number.times ^.x
                  ^.x.put
                    ^.x.as-number.plus 1
          true

This code will print this:

2 x 2 = 4
3 x 3 = 9
4 x 4 = 16
5 x 5 = 25

Got the idea?

Backus-Naur Form

This is our EBNF, of EO language:

ENBF of EO

This is the EBNF of πœ‘-calculus:

ENBF of πœ‘-calculus

The images were auto-generated. It's better to use ebnf/Eo.svg and ebnf/Phi.svg.

What's Next?

Join our Telegram group.

Watch video about EOLANG basics.

Read our blog, especially the section with recently published papers.

Learn XMIR, a dialect of XML, which we use to represent EO program: XSD is here, full specification is here.

See the full collection of canonical objects: objectionary.

Take a look how we use EO as an Intermediary Representation (IR) in Polystat, a polyglot static analyzer.

Play with more examples here.

Read about integration with Maven, here.

Benchmark

This is how many milliseconds were spent on different XSL stylesheets during the execution of mvn install of the eo-runtime module:

to-java.xsl                          68264  32.87%
add-refs.xsl                         24448  11.77%
set-locators.xsl                     12970  6.25%
tests.xsl                            10989  5.29%
rename-tests-inners.xsl              9114   4.39%
add-probes.xsl                       6215   2.99%
resolve-aliases.xsl                  5968   2.87%
vars-float-up.xsl                    5879   2.83%
classes.xsl                          5856   2.82%
add-default-package.xsl              5548   2.67%
explicit-data.xsl                    5511   2.65%
package.xsl                          5313   2.56%
cti-adds-errors.xsl                  5106   2.46%
expand-qqs.xsl                       4279   2.06%
clean-up.xsl                         4133   1.99%
atoms-with-bound-attrs.xsl           4106   1.98%

The results were calculated in this GHA job on 2024-12-23 at 05:07, on Linux with 4 CPUs. The total is 207665 milliseconds. We show only the first 16 most expensive XSL stylesheets.

You can run this benchmark locally with the following commands. First, to generate the measures.csv file:

mvn clean install --errors --batch-mode -Deo.xslMeasuresFile=measures.csv

Then, to generate the report:

awk -F ',' '{ a[$1]+=$2; s+=$2; } END { for (k in a) \
 printf("%s.xsl\t%d\t%0.2f%%\n", k, a[k], 100 * a[k]/s)}' \
 eo-runtime/measures.csv | sort -g -k 2 | tail -r | column -t | head "-16"

How to Contribute

Fork repository, make changes, then 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:

mvn clean install -Pqulice

You will need Maven 3.3+ and Java 11+ installed.

Special thanks

We are using the YourKit Java Profiler to enhance the performance of EO components:

YourKit