PHPnews.io

Abstract Objects

Written by Yegor Bugayenko / Original link on Dec. 1, 2020

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?

the-irishman.jpg
The Irishman (2019) by Martin Scorsese

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?

yegor256 oop yegor256

« The Advent of Code [blog] - Customise the caret color with the CSS `caret-color` property »