How do you create objects in your object-oriented language? Let’s take something classic, like C++, Java, or C#. First you define a class, and then you make an instance of it. The first step is known as abstraction, and the second one as instantiation. A similar pair of operations exist in functional programming: declaring a function is abstraction, while calling it with specific arguments is application. The question is: why does OOP need classes and objects, while FP survives with just functions?
This is an abstract object in EO:
[id db] > book
db.query > title
"SELECT title FROM book WHERE id=?"
id
The name of the object is book
. It has three attributes: id
, db
, and title
. The first two are “free”: they are not bound to any objects yet. The third one title
is bound already to a copy of the object db.query
. The object book
is abstract because it has some free attributes—it’s not specific enough to refer to a specific entity in the real world.
The construct db.query
takes an abstract object query
from the object bound to the attribute db
and makes a copy of it, specifying two arguments: the SQL string and the id
. The process of copying an abstract object is called “application,” since it’s very similar to applying arguments to a function in FP.
The right way to use an abstract book
is to make a copy of it, specifying the arguments:
book 42 mysql > b
Here, 42
is the id
, mysql
is the db
and b
is a new object—a copy of the book
. In 𝜑-calculus, which is foundational to the EO programming language, this would be written as the following formula:
b ↤ book(42, mysql)
In order to get the title
of b
and name it t
, we just do:
b.title > t
We can also put it all together in one line:
(book 42 mysql).title > t
It’s possible to apply some arguments to an abstract object leaving other attributes still free. For example, this would make another abstract object, still requiring the id
to be specified in order to become a closed object:
book mysql:db > x
The suffix :db
helps the compiler understand which free attribute should be bound to the object mysql
. Later, x
can be copied again and a closed object b
will be created:
x 42 > b
Even though the syntax of EO makes it possible to say book.title
, it will lead to a compile-time error: It’s prohibited to touch free attributes of an abstract object or attributes that depend on other free attributes. However, let’s say we add a new attribute print
to the book
, in order to print it’s id
to the console we would do the following:
[id db] > book
stdout > print
sprintf
"The book ID is %d"
id
db.query > title
"SELECT title FROM book WHERE id=?"
id
The attribute print
doesn’t need the db
attribute to be bound, since it doesn’t use it. It’s possible to copy the book
with just id
and then call print
(assuming it’s happening in an EO interactive console):
$ book 42:id > x
x
$ x.print
The book ID is 42
By the way, do you know any other languages with abstract objects or is EO the first one to introduce this design?