├── .gitattributes
├── .github
└── workflows
│ ├── actionlint.yml
│ ├── checkmake.yml
│ ├── copyrights.yml
│ ├── latexmk.yml
│ ├── markdown-lint.yml
│ ├── pdd.yml
│ ├── reuse.yml
│ ├── typos.yml
│ ├── xcop.yml
│ └── yamllint.yml
├── .gitignore
├── .gitmodules
├── .latexmkrc
├── .rultor.yml
├── .texsc
├── CITATION.cff
├── DEPENDS.txt
├── LICENSE.txt
├── LICENSES
└── MIT.txt
├── Makefile
├── README.md
├── REUSE.toml
├── aspell.en.pws
├── goto-pic.pdf
├── paper.tex
└── renovate.json
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Check out all text files in UNIX format, with LF as end of line
2 | # Don't change this file. If you have any ideas about it, please
3 | # submit a separate issue about it and we'll discuss.
4 |
5 | * text=auto eol=lf
6 | *.java ident
7 | *.xml ident
8 | *.png binary
9 |
--------------------------------------------------------------------------------
/.github/workflows/actionlint.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
2 | # SPDX-License-Identifier: MIT
3 | ---
4 | # yamllint disable rule:line-length
5 | name: actionlint
6 | 'on':
7 | push:
8 | branches:
9 | - master
10 | pull_request:
11 | branches:
12 | - master
13 | jobs:
14 | actionlint:
15 | timeout-minutes: 15
16 | runs-on: ubuntu-24.04
17 | steps:
18 | - uses: actions/checkout@v4
19 | - name: Download actionlint
20 | id: get_actionlint
21 | run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
22 | shell: bash
23 | - name: Check workflow files
24 | run: ${{ steps.get_actionlint.outputs.executable }} -color
25 | shell: bash
26 |
--------------------------------------------------------------------------------
/.github/workflows/checkmake.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
2 | # SPDX-License-Identifier: MIT
3 | ---
4 | name: checkmake
5 | 'on':
6 | push:
7 | branches:
8 | - master
9 | pull_request:
10 | branches:
11 | - master
12 | jobs:
13 | checkmake:
14 | timeout-minutes: 15
15 | runs-on: ubuntu-24.04
16 | steps:
17 | - uses: actions/checkout@v4
18 | - uses: Uno-Takashi/checkmake-action@v2
19 |
--------------------------------------------------------------------------------
/.github/workflows/copyrights.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
2 | # SPDX-License-Identifier: MIT
3 | ---
4 | # yamllint disable rule:line-length
5 | name: copyrights
6 | 'on':
7 | push:
8 | branches:
9 | - master
10 | pull_request:
11 | branches:
12 | - master
13 | jobs:
14 | copyrights:
15 | timeout-minutes: 15
16 | runs-on: ubuntu-24.04
17 | steps:
18 | - uses: actions/checkout@v4
19 | - uses: yegor256/copyrights-action@0.0.8
20 |
--------------------------------------------------------------------------------
/.github/workflows/latexmk.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
2 | # SPDX-License-Identifier: MIT
3 | ---
4 | # yamllint disable rule:line-length
5 | name: latexmk
6 | 'on':
7 | push:
8 | pull_request:
9 | jobs:
10 | build:
11 | timeout-minutes: 15
12 | runs-on: ubuntu-24.04
13 | steps:
14 | - uses: actions/checkout@v4
15 | - uses: yegor256/latexmk-action@0.16.1
16 | with:
17 | opts: -pdf
18 | depends: DEPENDS.txt
19 | - run: |
20 | mkdir gh-pages
21 | cp paper.pdf gh-pages
22 | - uses: JamesIves/github-pages-deploy-action@v4.7.3
23 | with:
24 | branch: gh-pages
25 | folder: gh-pages
26 | clean: false
27 |
--------------------------------------------------------------------------------
/.github/workflows/markdown-lint.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
2 | # SPDX-License-Identifier: MIT
3 | ---
4 | # yamllint disable rule:line-length
5 | name: markdown-lint
6 | 'on':
7 | push:
8 | branches:
9 | - master
10 | pull_request:
11 | branches:
12 | - master
13 | jobs:
14 | markdown-lint:
15 | timeout-minutes: 15
16 | runs-on: ubuntu-24.04
17 | steps:
18 | - uses: actions/checkout@v4
19 | - uses: DavidAnson/markdownlint-cli2-action@v20.0.0
20 |
--------------------------------------------------------------------------------
/.github/workflows/pdd.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
2 | # SPDX-License-Identifier: MIT
3 | ---
4 | # yamllint disable rule:line-length
5 | name: pdd
6 | 'on':
7 | push:
8 | branches:
9 | - master
10 | pull_request:
11 | branches:
12 | - master
13 | jobs:
14 | pdd:
15 | timeout-minutes: 15
16 | runs-on: ubuntu-24.04
17 | steps:
18 | - uses: actions/checkout@v4
19 | - uses: volodya-lombrozo/pdd-action@master
20 |
--------------------------------------------------------------------------------
/.github/workflows/reuse.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
2 | # SPDX-License-Identifier: MIT
3 | ---
4 | # yamllint disable rule:line-length
5 | name: reuse
6 | 'on':
7 | push:
8 | branches:
9 | - master
10 | pull_request:
11 | branches:
12 | - master
13 | jobs:
14 | reuse:
15 | timeout-minutes: 15
16 | runs-on: ubuntu-24.04
17 | steps:
18 | - uses: actions/checkout@v4
19 | - uses: fsfe/reuse-action@v5
20 |
--------------------------------------------------------------------------------
/.github/workflows/typos.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
2 | # SPDX-License-Identifier: MIT
3 | ---
4 | # yamllint disable rule:line-length
5 | name: typos
6 | 'on':
7 | push:
8 | branches:
9 | - master
10 | pull_request:
11 | branches:
12 | - master
13 | jobs:
14 | typos:
15 | timeout-minutes: 15
16 | runs-on: ubuntu-24.04
17 | steps:
18 | - uses: actions/checkout@v4
19 | - uses: crate-ci/typos@v1.32.0
20 |
--------------------------------------------------------------------------------
/.github/workflows/xcop.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
2 | # SPDX-License-Identifier: MIT
3 | ---
4 | # yamllint disable rule:line-length
5 | name: xcop
6 | 'on':
7 | push:
8 | branches:
9 | - master
10 | pull_request:
11 | branches:
12 | - master
13 | jobs:
14 | xcop:
15 | timeout-minutes: 15
16 | runs-on: ubuntu-24.04
17 | steps:
18 | - uses: actions/checkout@v4
19 | - uses: g4s8/xcop-action@master
20 |
--------------------------------------------------------------------------------
/.github/workflows/yamllint.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
2 | # SPDX-License-Identifier: MIT
3 | ---
4 | # yamllint disable rule:line-length
5 | name: yamllint
6 | 'on':
7 | push:
8 | branches:
9 | - master
10 | pull_request:
11 | branches:
12 | - master
13 | jobs:
14 | yamllint:
15 | timeout-minutes: 15
16 | runs-on: ubuntu-24.04
17 | steps:
18 | - uses: actions/checkout@v4
19 | - uses: ibiqlik/action-yamllint@v3
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | _minted-*
2 | .DS_Store
3 | .idea/
4 | *.aux
5 | *.bbl
6 | *.bcf
7 | *.blg
8 | *.fdb_latexmk
9 | *.fls
10 | *.log
11 | *.out
12 | *.pyg
13 | *.run.xml
14 | *.synctex.gz
15 | *.zip
16 | node_modules/
17 | package/
18 | paper.pdf
19 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "bibliography"]
2 | path = bibliography
3 | url = https://github.com/yegor256/bibliography
4 |
--------------------------------------------------------------------------------
/.latexmkrc:
--------------------------------------------------------------------------------
1 | $pdflatex = 'pdflatex %O --shell-escape %S';
2 | $success_cmd = 'texqc && texsc';
3 |
--------------------------------------------------------------------------------
/.rultor.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
2 | # SPDX-License-Identifier: MIT
3 | ---
4 | # yamllint disable rule:line-length
5 | architect:
6 | - yegor256
7 | docker:
8 | image: yegor256/rultor-image:1.24.0
9 | install: |
10 | sudo apt-get install --yes python3-pygments
11 | sudo pip3 install pygments
12 | pdd --file=/dev/null
13 | sudo tlmgr option repository ctan
14 | sudo tlmgr --verify-repo=none update --self
15 | sudo tlmgr --verify-repo=none install $(cut -d' ' -f2 DEPENDS.txt | uniq)
16 | sudo tlmgr --verify-repo=none update $(cut -d' ' -f2 DEPENDS.txt | uniq)
17 | merge:
18 | script: |
19 | latexmk -pdf
20 |
--------------------------------------------------------------------------------
/.texsc:
--------------------------------------------------------------------------------
1 | --pws=aspell.en.pws
2 | --ignore=nospell
3 | --ignore=equation*
4 | --ignore=ffcode
5 | --ignore=setminted
6 | --ignore=opt,grp,T,V,few,RE
7 | --ignore=newminted:opp
8 | --ignore=newtcbox:pp
9 | --ignore=settopmatter
10 | --ignore=CJK
11 | --ignore=lref:p,lrefs:pp
12 | --ignore=tikzstyle,tikzpicture,usetikzlibrary,ingraph
13 | --ignore=tikz:op
14 | --ignore=textcolor:pp
15 | --ignore=newmdenv:op
16 | --ignore=f,code,nospell,citet,citep
17 |
--------------------------------------------------------------------------------
/CITATION.cff:
--------------------------------------------------------------------------------
1 | cff-version: 1.2.0
2 | message: "If you use this software, please cite it as below."
3 | authors:
4 | - family-names: "Bugayenko"
5 | given-names: "Yegor"
6 | orcid: "https://orcid.org/0000-0001-6370-0678"
7 | title: "Reducing Programs to Objects"
8 | version: 0.23.0
9 | doi: 10.48550/arXiv.2112.11988
10 | date-released: 2022-05-09
11 | url: "https://github.com/objectionary/reducing-programs-to-objects"
12 |
--------------------------------------------------------------------------------
/DEPENDS.txt:
--------------------------------------------------------------------------------
1 | hard acmart
2 | hard algorithmicx
3 | hard algpseudocodex
4 | hard anyfontsize
5 | hard babel-russian
6 | hard biblatex
7 | hard cancel
8 | hard catchfile
9 | hard cjk
10 | hard cm-super
11 | hard comment
12 | hard currfile
13 | hard cyrillic
14 | hard datetime
15 | hard enumitem
16 | hard environ
17 | hard fdsymbol
18 | hard ffcode
19 | hard fmtcount
20 | hard footmisc
21 | hard framed
22 | hard fvextra
23 | hard href-ul
24 | hard hyperxmp
25 | hard hyphen-russian
26 | hard iexec
27 | hard ifmtarg
28 | hard lastpage
29 | hard lh
30 | hard libertine
31 | hard makecell
32 | hard ncctools
33 | hard paralist
34 | hard preprint
35 | hard stmaryrd
36 | hard svg
37 | hard textpos
38 | hard titling
39 | hard to-be-determined
40 | hard totpages
41 | hard transparent
42 | hard trimspaces
43 | hard upquote
44 | hard wrapfig
45 | hard xstring
46 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | (The MIT License)
2 |
3 | Copyright (c) 2024-2025 Yegor Bugayenko
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the 'Software'), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LICENSES/MIT.txt:
--------------------------------------------------------------------------------
1 | (The MIT License)
2 |
3 | Copyright (c) 2024-2025 Yegor Bugayenko
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the 'Software'), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Copyright (c) 2020-2025 Yegor Bugayenko
2 | # SPDX-License-Identifier: MIT
3 |
4 | .SHELLFLAGS = -e -x -c
5 | .ONESHELL:
6 |
7 | TLROOT=$$(kpsewhich -var-value TEXMFDIST)
8 | PACKAGES=ffcode to-be-determined href-ul
9 | REPO=objectionary/reducing-programs-to-objects
10 |
11 | zip: *.tex
12 | rm -rf package
13 | mkdir package
14 | cd package
15 | cp ../paper.tex .
16 | cp ../acmart.cls .
17 | cp ../main.bib .
18 | cp ../goto-pic.pdf .
19 | for p in $(PACKAGES); do cp $(TLROOT)/tex/latex/$${p}/$${p}.sty .; done
20 | version=$$(curl --silent -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/$(REPO)/releases/latest | jq -r '.tag_name')
21 | echo "Version is: $${version}"
22 | gsed -i "s|0\.0\.0|$${version}|" paper.tex
23 | gsed -i "s|REPOSITORY|$(REPO)|" paper.tex
24 | pdflatex -shell-escape -halt-on-error paper.tex
25 | biber paper
26 | pdflatex -halt-on-error paper.tex
27 | pdflatex -halt-on-error paper.tex
28 | rm -rf *.aux *.bcf *.blg *.fdb_latexmk *.fls *.log *.run.xml *.out *.exc
29 | zip -x paper.pdf -r paper-$${version}.zip *
30 | mv paper-$${version}.zip ..
31 | cd ..
32 |
33 | clean:
34 | git clean -dfX
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | [](https://arxiv.org/abs/2112.11988)
4 | [](https://github.com/yegor256/reducing-programs-to-objects/actions/workflows/latexmk.yml)
5 |
6 | The paper is published [in arXiv](https://arxiv.org/abs/2112.11988) (draft is [here](https://github.com/objectionary/reducing-programs-to-objects/blob/gh-pages/paper.pdf)).
7 |
8 | To build it, just run:
9 |
10 | ```bash
11 | $ make
12 | ```
13 |
14 | You need to have
15 | [`aspell`](http://aspell.net/),
16 | LaTeX,
17 | [`biblint`](https://github.com/Kingsford-Group/biblint),
18 | [`texsc`](https://rubygems.org/gems/texsc),
19 | and
20 | [`texqc`](https://rubygems.org/gems/texqc)
21 | installed.
22 |
23 | Once compiled and packaged, upload zip archive to [arXiv](https://arxiv.org/abs/2112.11988).
24 |
--------------------------------------------------------------------------------
/REUSE.toml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Copyright (c) 2025 Yegor Bugayenko
2 | # SPDX-License-Identifier: MIT
3 |
4 | version = 1
5 | [[annotations]]
6 | path = [
7 | ".DS_Store",
8 | ".gitattributes",
9 | ".gitignore",
10 | ".gitmodules",
11 | ".latexmkrc",
12 | ".texsc",
13 | "**.jpg",
14 | "**.json",
15 | "**.md",
16 | "**.pdf",
17 | "**.png",
18 | "**.txt",
19 | "**/.DS_Store",
20 | "**/.gitignore",
21 | "**/.gitmodules",
22 | "**/.latexmkrc",
23 | "**/.texsc",
24 | "**/*.csv",
25 | "**/*.jpg",
26 | "**/*.json",
27 | "**/*.md",
28 | "**/*.pdf",
29 | "**/*.png",
30 | "**/*.svg",
31 | "**/*.txt",
32 | "**/*.vm",
33 | "**/aspell.en.pws",
34 | "**/CITATION.cff",
35 | "**/CNAME",
36 | "**/DEPENDS.txt",
37 | "aspell.en.pws",
38 | "CITATION.cff",
39 | "DEPENDS.txt",
40 | "rc",
41 | "README.md",
42 | "renovate.json",
43 | ]
44 | precedence = "override"
45 | SPDX-FileCopyrightText = "Copyright (c) 2025 Yegor Bugayenko"
46 | SPDX-License-Identifier = "MIT"
47 |
--------------------------------------------------------------------------------
/aspell.en.pws:
--------------------------------------------------------------------------------
1 | personal_ws-1.1 en 741 utf-8
2 | Yegor
3 | Bugayenko
4 | Huawei
5 | Mixins
6 | goto
7 | minimalistic
8 |
--------------------------------------------------------------------------------
/goto-pic.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/objectionary/reducing-programs-to-objects/9c9d566c9588f30d00f455d6bdef1201241ee921/goto-pic.pdf
--------------------------------------------------------------------------------
/paper.tex:
--------------------------------------------------------------------------------
1 | % SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
2 | % SPDX-License-Identifier: MIT
3 |
4 | \documentclass[sigplan,11pt,nonacm,natbib=false]{acmart}
5 | \settopmatter{printfolios=false,printccs=false,printacmref=false}
6 | \usepackage[maxnames=1,minnames=1,maxbibnames=100,natbib=true,citestyle=authoryear,bibstyle=authoryear,doi=false,url=false,isbn=false,isbn=false,backend=biber]{biblatex}
7 | \ifnum\pdfshellescape=1
8 | \usepackage[finalizecache]{minted}
9 | \else
10 | \usepackage[frozencache]{minted}
11 | \fi
12 | \usepackage[nocn]{ffcode}
13 | \usepackage{tikz}
14 | \usepackage{to-be-determined}
15 | \setlength\footskip{13pt}
16 |
17 | \addbibresource{main.bib}
18 |
19 | \title{Reducing Programs to Objects}
20 | \subtitle{
21 | Ver:
22 | \texorpdfstring{
23 | \href{https://github.com/REPOSITORY/releases/tag/0.0.0}
24 | {\ff{0.0.0}}
25 | }{0.0.0}
26 | }
27 | \author{Yegor Bugayenko}
28 | \affiliation{\institution{Huawei}\country{Russia}\city{Moscow}}
29 | \email{yegor256@gmail.com}
30 |
31 | \begin{abstract}
32 | C++, Java, C\#, Python, Ruby, JavaScript are the most powerful object-oriented programming languages, if language power would be defined as the number of \emph{features} available for a programmer. EO, on the other hand, is an object-oriented programming language with a reduced set of features: it has nothing by objects and mechanisms of their composition and decoration. We are trying to answer the following research question: ``Which known features are possible to implement using only objects?''
33 | \end{abstract}
34 |
35 | \begin{document}
36 | \raggedbottom
37 |
38 | \maketitle
39 |
40 | \section{Features}
41 |
42 | To answer our research question we selected most complex features and demonstrated how each of them may be represented in EO~\citep{bugayenko2021eolang} objects\footnote{%
43 | \LaTeX{} sources of this paper are maintained in
44 | \href{https://github.com/REPOSITORY}{REPOSITORY} GitHub repository,
45 | the rendered version is \href{https://github.com/REPOSITORY/releases/tag/0.0.0}{\ff{0.0.0}}.}:
46 |
47 | \begin{itemize}
48 | \item Non-conditional jumps
49 | (Sec.~\ref{sec:goto}),
50 | \item Data and code pointers
51 | (Sec.~\ref{sec:pointers}),
52 | \item Procedures
53 | (Sec.~\ref{sec:procedures}),
54 | \item Classes
55 | (Sec.~\ref{sec:classes}),
56 | \item Exceptions
57 | (Sec.~\ref{sec:exceptions}),
58 | \item Anonymous functions
59 | (Sec.~\ref{sec:blocks}),
60 | \item Generators
61 | (Sec.~\ref{sec:generators}),
62 | \item Types and casting
63 | (Sec.~\ref{sec:types}),
64 | \item Reflection
65 | (Sec.~\ref{sec:reflection}),
66 | \item Static methods
67 | (Sec.~\ref{sec:static}),
68 | \item Inheritance
69 | (Sec.~\ref{sec:inheritance}),
70 | \item Method overloading
71 | (Sec.~\ref{sec:overloading}),
72 | \item Java generics
73 | (Sec.~\ref{sec:generics}),
74 | \item C++ templates
75 | (Sec.~\ref{sec:templates}),
76 | \item Mixins
77 | (Sec.~\ref{sec:mixins}),
78 | \item Java annotations
79 | (Sec.~\ref{sec:annotations}).
80 | \end{itemize}
81 |
82 | Other features are more trivial, that's why they are not presented in this paper, such as operators, loops, variables, code blocks, constants, branching, and so on.
83 |
84 | \subsection{Goto}
85 | \label{sec:goto}
86 |
87 | Goto is a one-way imperative transfer of control to another line of code. There are only two possible cases of goto jumps: forward and backward.
88 |
89 | \subsubsection{Backward Jump}
90 |
91 | This is a ``backward'' jump example in C language:
92 |
93 | \begin{ffcode}
94 | #include "stdio.h"
95 | void f() {
96 | int i = 1;
97 | again:
98 | i++;
99 | if (i < 10) goto again;
100 | printf("Finished!");
101 | }
102 | \end{ffcode}
103 |
104 | It can be mapped to the following EO code:
105 |
106 | \begin{ffcode}
107 | [] > f
108 | memory 0 > i
109 | seq > @
110 | i.write 1
111 | goto
112 | [g]
113 | seq > @
114 | i.write (i.plus 1)
115 | if.
116 | i.lt 10
117 | g.backward
118 | TRUE
119 | QQ.io.stdout "Finished!"
120 | \end{ffcode}
121 |
122 | Here, the one-argument abstract atom \ff{goto} is being copied with a one-argument abstract anonymous object, which is the sequence of objects doing the increment of \ff{i} and then the comparison of it with the number ten. If the condition is true, \ff{g.backward} is called, which leads to a backward jump and re-iteration of \ff{goto}.
123 |
124 | \subsubsection{Forward Jump}
125 |
126 | This is an example of a ``forward'' jump in C language:
127 |
128 | \begin{ffcode}
129 | int f(int x) {
130 | int r = 0;
131 | if (x == 0) goto exit;
132 | r = 42 / x;
133 | exit:
134 | return r;
135 | }
136 | \end{ffcode}
137 |
138 | It can be mapped to the following EO code:
139 |
140 | \begin{ffcode}
141 | [x] > f
142 | memory 0 > r
143 | seq > @
144 | r.write 0
145 | goto
146 | [g]
147 | seq > @
148 | if.
149 | x.eq 0
150 | g.forward TRUE
151 | TRUE
152 | r.write (42.div x)
153 | r
154 | \end{ffcode}
155 |
156 | Here, the same abstract atom \ff{goto} is copied with an abstract one-argument object, which is a sequence of objects. When the condition is true, a forward jump is performed by \ff{g.forward} atom.
157 |
158 | Similar way, the atom \ff{goto} may be used to simulate other conditional jump statements, like \ff{break}, \ff{continue}, or \ff{return} in the middle of a function body (see Sec.~\ref{sec:procedures}).
159 |
160 | \subsubsection{Complex Case}
161 |
162 | This is a more complex case of using \ff{goto} in C:
163 |
164 | \begin{ffcode}
165 | #include "stdio.h"
166 | void f(int a, int b) {
167 | goto start;
168 | back:
169 | printf("A");
170 | start:
171 | if (a > b) goto back;
172 | printf("B");
173 | }
174 | \end{ffcode}
175 |
176 | In order to translate this code to EO it has to be refactored as Fig.~\ref{fig:goto} demonstrates. The function \ff{f()} is copied twice and each copy has its own execution flow implemented.
177 |
178 | \begin{figure}
179 | \includegraphics[width=0.9\columnwidth]{goto-pic}
180 | \caption{The function \ff{f} with a few \ff{goto} statements inside is translated to two functions, reducing the complexity of the code at the cost of introducing duplication.}
181 | \Description{Workflow of GOTO object}
182 | \label{fig:goto}
183 | \end{figure}
184 |
185 | \begin{ffcode}
186 | #include "stdio.h"
187 | void f(int a, int b) { f1(a, b); }
188 | void f1(int a, int b) {
189 | if (a > b) f2(a, b);
190 | printf("B");
191 | }
192 | void f2(int a, int b) {
193 | back:
194 | printf("A");
195 | if (a > b) goto back;
196 | printf("B");
197 | }
198 | \end{ffcode}
199 |
200 | Then, the translation to EO is trivial, with the use of the \ff{goto} object.
201 |
202 | In more complex cases a program may first be restructured to replace \ff{goto} statements with loops and branching, as suggested by~\citet{williams1985restructuring,pan1996formal,erosa1994taming,ceccato2008goto}.
203 |
204 | \subsubsection{Multiple Returns}
205 |
206 | Some structured programming languages allow a function to exit at an arbitrary place, not only at the end, using \ff{return} statements, for example:
207 |
208 | \begin{ffcode}
209 | void abs(int x) {
210 | if (x > 0) {
211 | return x;
212 | }
213 | return -1 * x;
214 | }
215 | \end{ffcode}
216 |
217 | This can be mapped to the following EO code using \ff{goto} object:
218 |
219 | \begin{ffcode}
220 | [x] > abs
221 | goto > @
222 | [g]
223 | seq > @
224 | if.
225 | x.gt 0
226 | g.forward x
227 | TRUE
228 | g.forward
229 | -1.times x
230 | \end{ffcode}
231 |
232 | The dataization of \ff{g.forward} will exit the \ff{goto} object wrapping the entire code in the ``function'' \ff{abs}.
233 |
234 | \subsection{Pointers}
235 | \label{sec:pointers}
236 |
237 | A pointer is an object in many programming languages that stores a memory address. Pointers may point to data memory and to program memory.
238 |
239 | \subsubsection{Pointers to Data}
240 |
241 | This is an example of C code, where the pointer \ff{p} is first incremented by seven times \ff{sizeof(book)} (which is equal to 108) and then de-referenced to become a struct \ff{book} mapped to memory. Then, the \ff{title} part of the struct is filled with a string and the \ff{price} part is returned as a result of the function \ff{f}:
242 |
243 | \begin{ffcode}
244 | #include "string.h"
245 | struct book {
246 | char title[100];
247 | long long price;
248 | };
249 | int f(struct book* p) {
250 | struct book b = *(p + 7);
251 | strcpy(b.title, "Object Thinking");
252 | return b.price;
253 | }
254 | \end{ffcode}
255 |
256 | This code can be mapped to the following EO code:
257 |
258 | \begin{ffcode}
259 | [ptr] > book
260 | ptr > @
261 | ptr.block > title
262 | 100
263 | [b] (b.as-string > @)
264 | ptr.block > price
265 | 8
266 | [b] (b.as-int > @)
267 | pointer. > p1
268 | heap 1024
269 | 0
270 | 108
271 | [p] > f
272 | seq > @
273 | book (p.add 7) > b
274 | b.title.write
275 | ("Object Thinking").as-bytes
276 | b.price
277 | \end{ffcode}
278 |
279 | Here, \ff{p1} is an object that can be used as an argument of \ff{f}. It is a copy of an abstract object \ff{heap.pointer}, which expects two: 1)~an absolute address in memory, and 2)~the size of the memory block it points to, in bytes. Its attribute \ff{block} expects two attributes: 1) the number of bytes in the heap, and 2)~an abstract object that can encapsulate \ff{bytes} which were just read from memory.
280 |
281 | The object \ff{heap} is an abstraction of a random access memory.
282 |
283 | \subsubsection{Pointers to Code}
284 |
285 | A pointer may not only refer to data in the heap, but also to executable code in memory (there is no difference between ``program'' and ``data'' memories both in x86 and ARM architectures). This is an example of C program, which calls a function referenced by a function pointer, providing two integer arguments to it:
286 |
287 | \begin{ffcode}
288 | int foo(int x, int y) {
289 | return x + y;
290 | }
291 | int f() {
292 | int (*p)(int, int);
293 | p = &foo;
294 | return (*p) (7, 42);
295 | }
296 | \end{ffcode}
297 |
298 | This code can be mapped to the following EO code:
299 |
300 | \begin{ffcode}
301 | [x y] > foo
302 | x.plus y > @
303 | [] > f
304 | cage 0 > p
305 | seq > @
306 | p.write
307 | [x y]
308 | foo x y > @
309 | p.@ 7 42
310 | \end{ffcode}
311 |
312 | Important to notice that the following code is not possible to represent in EO:
313 |
314 | \begin{ffcode}
315 | int f() {
316 | int (*p)(int);
317 | p = (int(*)(int)) 0x761AFE65;
318 | return (*p) (42);
319 | }
320 | \end{ffcode}
321 |
322 | Here, the pointer refers to an arbitrary address in program memory, where some executable code is supposed to be located.
323 |
324 | \subsubsection{Variables in Stack}
325 |
326 | This C function, which returns seven (tested with GCC), assumes that variables are placed in stack sequentially and uses pointer de-referencing to access them:
327 |
328 | \begin{ffcode}
329 | int f() {
330 | long long a = 42;
331 | long long b = 7;
332 | return *(&a - 1);
333 | }
334 | \end{ffcode}
335 |
336 | This code can be mapped to the following EO code:
337 |
338 | \begin{ffcode}
339 | [p] > long64
340 | p.block > @
341 | 8
342 | [b] (b.as-int > @)
343 | [] > f
344 | seq > @
345 | malloc. > stack
346 | heap 32 > h
347 | 16
348 | long64 stack > b
349 | b.write (7.as-bytes)
350 | long64 stack > a
351 | a.write (42.as-bytes)
352 | long64 (a.p.sub 1) > ret!
353 | h.free stack
354 | ret
355 | \end{ffcode}
356 |
357 | Here, the atom \ff{malloc} allocates a segment of bytes in the \ff{heap}. Later, the atom \ff{free} releases it. The attribute \ff{ret} is made constant in order to avoid its recalculation after it's ``returned'' (this mechanism is explained in Sec.~\ref{sec:destructors} where destructors are discussed).
358 |
359 | \subsection{Procedures}
360 | \label{sec:procedures}
361 |
362 | A subroutine is a sequence of program instructions that performs a specific task, packaged as a unit. In different programming languages, a subroutine may be called a routine, subprogram, function, method, or procedure. In this PHP example, a function \ff{max} is defined:
363 |
364 | \begin{ffcode}
365 | function max($a, $b) {
366 | if ($a > $b) return $a;
367 | return $b;
368 | }
369 | \end{ffcode}
370 |
371 | It can be mapped to the following EO code:
372 |
373 | \begin{ffcode}
374 | [a b] > max
375 | goto > @
376 | [g]
377 | seq > @
378 | if.
379 | a.gt b
380 | g.forward a
381 | TRUE
382 | b
383 | \end{ffcode}
384 |
385 | This example also demonstrates how \ff{goto} object can be used to simulate the behavior of the \ff{return} statement from within the body of a method.
386 |
387 | \subsubsection{Impure Functions}
388 |
389 | A function is pure when, among other qualities, it doesn't have side effects:
390 | no mutation of local static variables, non-local variables, mutable reference arguments
391 | or input/output streams. This PHP function is impure:
392 |
393 | \begin{ffcode}
394 | $a = 42;
395 | function inc($a) {
396 | $a = $a + 1;
397 | return $a;
398 | }
399 | inc(inc($a)); // $a == 44
400 | \end{ffcode}
401 |
402 | It may be mapped to a constant EO object:
403 |
404 | \begin{ffcode}
405 | memory 42 > a
406 | [x] > inc!
407 | seq > @
408 | x.write
409 | x.plus 1
410 | inc
411 | inc a
412 | \end{ffcode}
413 |
414 | \subsection{Classes}
415 | \label{sec:classes}
416 |
417 | A class is an extensible program-code-template for creating objects, providing initial values for state (member variables) and implementations of behavior (member functions or methods). The following program contains a Ruby class with a single constructor, two methods, and one mutable member variable:
418 |
419 | \begin{ffcode}
420 | class Book
421 | def initialize(i)
422 | @id = id
423 | puts "New book!"
424 | end
425 | def path
426 | "/tmp/${@id}.txt"
427 | end
428 | def move(i)
429 | @id = i
430 | end
431 | end
432 | \end{ffcode}
433 |
434 | It can be mapped to the following EO code, where a class becomes a factory of objects:
435 |
436 | \begin{ffcode}
437 | [i] > book
438 | cage i > id
439 | [] > ruby-init
440 | QQ.txt.sprintf > @
441 | "New book!"
442 | [] > path
443 | QQ.txt.sprintf > @
444 | "/tmp/%s.txt"
445 | id
446 | [i] > move
447 | id.write i > @
448 | \end{ffcode}
449 |
450 | Here, the constructor is represented by the object \ff{ruby-init}, which initializes finishes the initization of the object. The making an ``instance'' of a book would look like this:
451 |
452 | \begin{ffcode}
453 | book 42 > b
454 | b.ruby-init
455 | b.move 7
456 | b.path
457 | \end{ffcode}
458 |
459 | \subsection{Destructors}
460 | \label{sec:destructors}
461 |
462 | In C++ and some other languages, a destructor is a method that is called for a class object when that object passes out of scope or is explicitly deleted. The following code will print both \ff{Alive} and \ff{Dead} texts:
463 |
464 | \begin{ffcode}
465 | #include
466 | class Foo {
467 | public:
468 | Foo() { std::cout << "Alive"; }
469 | ~Foo() { std::cout << "Dead"; };
470 | };
471 | int main() {
472 | Foo f = Foo();
473 | }
474 | \end{ffcode}
475 |
476 | It may be translated to EO as such:
477 |
478 | \begin{ffcode}
479 | [] > foo
480 | [] > constructor
481 | QQ.io.stdout "Alive" > @
482 | [] > destructor
483 | QQ.io.stdout "Dead" > @
484 | [] > main
485 | foo > f
486 | seq > @
487 | f.constructor
488 | f.destructor
489 | \end{ffcode}
490 |
491 | There is no garbage collection in EO, that's why a destructor must be explicitly ``called'' when an object passes out of scope or is deleted.
492 |
493 | \subsection{Exceptions}
494 | \label{sec:exceptions}
495 |
496 | Exception handling is the process of responding to the occurrence of exceptions---anomalous or exceptional conditions requiring special processing---during the execution of a program provided. This C++ program utilizes exception handling to avoid segmentation fault due to null pointer de-referencing:
497 |
498 | \begin{ffcode}
499 | #include
500 | class Book { public: int price(); };
501 | int price(Book* b) {
502 | if (b == NULL) throw "NPE!";
503 | return (*b).price() * 1.1;
504 | }
505 | void print(Book* b) {
506 | try {
507 | std::cout << "The price: " << price(b);
508 | } catch (char const* e) {
509 | std::cout << "Error: " << e;
510 | }
511 | }
512 | \end{ffcode}
513 |
514 | This mechanism may be implemented in EO:
515 |
516 | \begin{ffcode}
517 | [] > book
518 | [] > price /int
519 | [b] > price
520 | if. > @
521 | b.eq 0
522 | error "NPE!"
523 | b.price.times 1.1
524 | [b] > print
525 | try > @
526 | []
527 | QQ.io.stdout > @
528 | QQ.txt.sprintf
529 | "The price: %d"
530 | price b
531 | [e]
532 | QQ.io.stdout > @
533 | QQ.txt.sprintf
534 | "Error: %s"
535 | e
536 | []
537 | nop > @
538 | \end{ffcode}
539 |
540 | Here, the object \ff{try} expects three arguments: 1)~an abstract object to be dataized, and 2)~an abstract object to be copied with one argument, in case dataization returns encapsulated object, and 3)~an object to be dataized anyway (similar to Java \ff{finaly} block).
541 |
542 | In the object \ff{price} we get the object \ff{error}, which if dataized, causes the termination of dataization and a non-conditional jump to the ``catch'' object of the \ff{try}. The mechanism is similar to ``checked'' exceptions in Java, where a method's signature must declare all types of exceptions the method may throw.
543 |
544 | \subsubsection{Many Exception Types}
545 |
546 | A Java method may throw a number of either checked or unchecked exceptions, for example:
547 |
548 | \begin{ffcode}
549 | void f(int x) throws IOException {
550 | if (x == 0) {
551 | throw new IOException();
552 | }
553 | throw new RuntimeException();
554 | }
555 | \end{ffcode}
556 |
557 | This would be represented in EO as such:
558 |
559 | \begin{ffcode}
560 | [x] > f
561 | if. > @
562 | x.eq 0
563 | error "IOException"
564 | error "RuntimeException"
565 | \end{ffcode}
566 |
567 | To catch both exceptions the object \ff{f} would be used like this:
568 |
569 | \begin{ffcode}
570 | try
571 | []
572 | try > @
573 | []
574 | f 5 > @
575 | [e1]
576 | QQ.io.stdout e1 > @
577 | []
578 | nop > @
579 | [e2]
580 | QQ.io.stdout e2 > @
581 | []
582 | nop > @
583 | \end{ffcode}
584 |
585 | \subsection{Anonymous Functions}
586 | \label{sec:blocks}
587 |
588 | Anonymous functions that can be passed into methods as arguments. For example, in this Ruby code a ``block'' (a name Ruby uses for anonymous functions) is passed:
589 |
590 | \begin{ffcode}
591 | def scan(lines)
592 | lines.each do |t|
593 | if t.starts_with? '#' yield t
594 | end
595 | end
596 | scan(array) { |x| puts x }
597 | \end{ffcode}
598 |
599 | This mechanism may be implemented in EO:
600 |
601 | \begin{ffcode}
602 | [lines b] > scan
603 | lines.each > @
604 | [t]
605 | if. > @
606 | t.starts-with "#"
607 | b t
608 | TRUE
609 | scan
610 | array
611 | [x]
612 | QQ.io.stdout x > @
613 | \end{ffcode}
614 |
615 | Here, the anonymous function passed to the object \ff{scan} as an argument \ff{b}. The ``call'' of this function is the dataization of its copy, performed by the \ff{if} atom.
616 |
617 | \subsection{Generators}
618 | \label{sec:generators}
619 |
620 | A generator is a routine that can be used to control the iteration behaviour of a loop. For example, this PHP program will print first ten Fibonacci numbers:
621 |
622 | \begin{ffcode}
623 | function fibonacci(int $limit):generator {
624 | yield $a = $b = $i = 1;
625 | while (++$i < $limit) {
626 | $b = $a + $b;
627 | yield $b - $a;
628 | $a = $b;
629 | }
630 | }
631 | foreach (fibonacci(10) as $n) {
632 | echo "$n\n";
633 | }
634 | \end{ffcode}
635 |
636 | This mechanism may be implemented in EO:
637 |
638 | \begin{ffcode}
639 | [limit f] > fibonacci
640 | memory 0 > a
641 | memory 0 > b
642 | memory 0 > i
643 | seq > @
644 | a.write 1
645 | b.write 1
646 | f 0
647 | while.
648 | seq (i.write (i.plus 1)) (i.lt limit)
649 | [idx]
650 | seq > @
651 | b.write (a.plus b)
652 | a.write (b.minus a)
653 | f (b.minus a)
654 | TRUE
655 | fibonacci > @
656 | 10
657 | [n]
658 | QQ.io.stdout > @
659 | QQ.txt.sprintf "%d\n" n
660 | \end{ffcode}
661 |
662 | Here, the generator is turned into an abstract object \ff{fibonacci} with an extra parameter \ff{f}, which is specified with an abstract object argument, which prints what's given as \ff{n}.
663 |
664 | \subsection{Types and Type Casting}
665 | \label{sec:types}
666 |
667 | A type system is a logical system comprising a set of rules that assigns a property called a type to the various constructs of a computer program, such as variables, expressions, functions or modules. The main purpose of a type system is to reduce possibilities for bugs in computer programs by defining interfaces between different parts of a computer program, and then checking that the parts have been connected in a consistent way. In this example, a Java method \ff{add} expects an argument of type \ff{Book} and compilation would fail if another type is provided:
668 |
669 | \begin{ffcode}
670 | class Cart {
671 | private int total;
672 | void add(Book b) {
673 | this.total += b.price();
674 | }
675 | }
676 | \end{ffcode}
677 |
678 | The restrictions enforced by Java type system in compile time through types \ff{Cart} and \ff{Book} may be represented in EO by means of decorators, for example:
679 |
680 | \begin{ffcode}
681 | [] > original-cart
682 | memory 0 > total
683 | [b] > add
684 | total.write (total.plus (b.price))
685 | [] > cart
686 | original-cart > @
687 | [b] > add
688 | if.
689 | b.subtype-of (QQ.txt.text "Book")
690 | @.add b
691 | []
692 | error "Type mismatch, Book expected" > @
693 | \end{ffcode}
694 |
695 | Here, it is expected that the parameter \ff{b} is defined in a ``class,'' which has \ff{subtype-of} attribute, which may also be provided by a decorator (a simplified example):
696 |
697 | \begin{ffcode}
698 | [] > original-book
699 | memory 0 > price
700 | [] > book
701 | original-book > @
702 | [t] > subtype-of
703 | t.eq "Book" > @
704 | [] > price
705 | @.price > @
706 | \end{ffcode}
707 |
708 | This decoration may be simplified through a ``fluent'' supplementary object:
709 |
710 | \begin{ffcode}
711 | type "Cart" > cart-type
712 | .super-types "Object" "Printable"
713 | .method "add" "Book"
714 | cart-type original-cart > cart
715 | \end{ffcode}
716 |
717 | Here, the \ff{type} object implements all necessary restrictions Java type system may provide for the type \ff{Cart} and its methods.
718 |
719 | Type casting, which is a mechanism of changing an expression from one data type to another, may also be implemented through same decorators.
720 |
721 | \subsection{Reflection}
722 | \label{sec:reflection}
723 |
724 | Reflection is the ability of a process to examine, introspect, and modify its own structure and behavior. In the following Python example the method \ff{hello} of an instance of class \ff{Foo} is not called directly on the object, but is first retrieved through reflection functions \ff{globals} and \ff{getattr}, and then executed:
725 |
726 | \begin{ffcode}
727 | def Foo():
728 | def hello(self, name):
729 | print("Hello, %s!" % name)
730 | obj = globals()["Foo"]()
731 | getattr(obj, "hello")("Jeff")
732 | \end{ffcode}
733 |
734 | It may be implemented in EO just by encapsulating additional meta information in classes explained in Sec.~\ref{sec:classes}.
735 |
736 | \subsubsection{Monkey Patching}
737 |
738 | Monkey patching is making changes to a module or a class while the program is running. This JavaScript program adds a new method \ff{print} to the object \ff{b} after the object has already been instantiated:
739 |
740 | \begin{ffcode}
741 | function Book(t) { this.title = t; }
742 | var b = new Book("Object Thinking");
743 | b.print = function() {
744 | console.log(this.title);
745 | }
746 | b.print();
747 | \end{ffcode}
748 |
749 | This program may be translated to EO, assuming that \ff{b} is being held by an attribute of a larger object, for example \ff{app}:
750 |
751 | \begin{ffcode}
752 | [] > app
753 | cage 0 > b
754 | b' > copy
755 | seq > @
756 | b.write
757 | [] > book
758 | [t] > new
759 | memory "" > title
760 | title.write t > @
761 | copy.<
762 | b.write
763 | [] > book
764 | [t] > new
765 | seq > @
766 | []
767 | copy > @
768 | [] > print
769 | QQ.io.stdout (^.title)
770 | b.print
771 | \end{ffcode}
772 |
773 | Here, the modification to the object \ff{book} is happening through making a copy of it, creating a decorator, and then storing it to where the original object was located.
774 |
775 | \subsection{Static Methods}
776 | \label{sec:static}
777 |
778 | A static method (or static function) is a method defined as a member of an object but is accessible directly from an API object's constructor, rather than from an object instance created via the constructor. For example, this C\# class consists of a single static method:
779 |
780 | \begin{ffcode}
781 | class Utils {
782 | public static int max(int a, int b) {
783 | if (a > b) return a;
784 | return b;
785 | }
786 | }
787 | \end{ffcode}
788 |
789 | It may be converted to the following EO code, since a static method is nothing else but a ``global'' function:
790 |
791 | \begin{ffcode}
792 | [a b] > utils-max
793 | if. > @
794 | a.gt b
795 | a
796 | b
797 | \end{ffcode}
798 |
799 | \subsection{Inheritance}
800 | \label{sec:inheritance}
801 |
802 | Inheritance is the mechanism of basing a class upon another class retaining similar implementation. In this Java code class \ff{Book} inherits all methods and non-private attributes from class \ff{Item}:
803 |
804 | \begin{ffcode}
805 | class Item {
806 | private int p;
807 | int price() { return p; }
808 | }
809 | class Book extends Item {
810 | int tax() { return price() * 0.1; }
811 | }
812 | \end{ffcode}
813 |
814 | It may be represented in EO like this:
815 |
816 | \begin{ffcode}
817 | [] > item
818 | memory 0 > p
819 | [] > price
820 | p > @
821 | [] > book
822 | item > i
823 | [] > tax
824 | (QQ.math.number (i.price)).as-float.times 0.1 > @
825 | \end{ffcode}
826 |
827 | Here, composition is used instead of inheritance.
828 |
829 | \subsubsection{Prototype-Based Inheritance}
830 |
831 | So called pro\-to\-type-based programming uses generalized objects, which can then be cloned and extended. For example, this JavaScript program defines two objects, where \ff{Item} is the parent object and \ff{Book} is the child that inherits the parent through its prototype:
832 |
833 | \begin{ffcode}
834 | function Item(p) { this.price = p; }
835 | function Book(p) {
836 | Item.call(this, p);
837 | this.tax = function () {
838 | return this.price * 0.1;
839 | }
840 | }
841 | var t = new Book(42).tax();
842 | console.log(t); // prints "4.2"
843 | \end{ffcode}
844 |
845 | This mechanism of prototype-based inheritance may be translated to the following EO code, using the mechanism of decoration:
846 |
847 | \begin{ffcode}
848 | [p] > item
849 | memory 0 > price
850 | [] > new
851 | price.write p > @
852 | [] > book
853 | [p] > new
854 | item p > @
855 | [] > tax
856 | times. > @
857 | as-float.
858 | QQ.math.number (^.price)
859 | 0.1
860 | QQ.io.stdout
861 | QQ.txt.sprintf
862 | "%f"
863 | tax.
864 | book.new 42
865 | \end{ffcode}
866 |
867 | \subsubsection{Multiple Inheritance}
868 |
869 | Multiple inheritance is a feature of some object-oriented computer programming languages in which an object or class can inherit features from more than one parent object or parent class. In this C++ example,
870 | the class \ff{Jack} has both \ff{bark} and \ff{listen} methods, inherited from \ff{Dog} and \ff{Friend} respectively:
871 |
872 | \begin{ffcode}
873 | #include
874 | class Dog {
875 | virtual void bark() {
876 | std::cout << "Bark!";
877 | }
878 | };
879 | class Friend {
880 | virtual void listen();
881 | };
882 | class Jack: Dog, Friend {
883 | void listen() override {
884 | Dog::bark();
885 | std::cout << "Listen!";
886 | }
887 | };
888 | \end{ffcode}
889 |
890 | It may be represented in EO like this:
891 |
892 | \begin{ffcode}
893 | [] > dog
894 | [] > bark
895 | QQ.io.stdout "Bark!" > @
896 | [] > friend
897 | [] > listen
898 | [] > jack
899 | dog > d
900 | friend > f
901 | [] > listen
902 | seq > @
903 | d.bark
904 | QQ.io.stdout "listen!"
905 | \end{ffcode}
906 |
907 | Here, inherited methods are explicitly listen as attributes in the object \ff{jack}. This is very close to what would happen in the virtual table of a class \ff{Jack} in C++. The EO object \ff{jack} just makes it explicit.
908 |
909 | \subsection{Method Overloading}
910 | \label{sec:overloading}
911 |
912 | Method overloading is the ability to create multiple functions of the same name with different implementations. Calls to an overloaded function will run a specific implementation of that function appropriate to the context of the call, allowing one function call to perform different tasks depending on context. In this Kotlin program two functions are defined with the same name, while only one of them is called with an integer argument:
913 |
914 | \begin{ffcode}
915 | fun foo(a: Int) {}
916 | fun foo(a: Double) {}
917 | foo(42)
918 | \end{ffcode}
919 |
920 | It may be represented in EO like this:
921 |
922 | \begin{ffcode}
923 | [args...] > foo
924 | (args.at 0) > a0
925 | if.
926 | a0.subtype-of "Int"
927 | first-foo a0
928 | second-foo a0
929 | foo 42
930 | \end{ffcode}
931 |
932 | This code expects arguments of \ff{foo} to be equipped with the type system suggested in Sec.~\ref{sec:types}. The attribute \ff{subtype-of} will help dispatching the call to the right objects.
933 |
934 | \subsection{Java Generics}
935 | \label{sec:generics}
936 |
937 | Generics extend Java's type system to allow a type or method to operate on objects of various types while providing compile-time type safety. For example, this Java class expects another class to be specified as \ff{T} before usage:
938 |
939 | \begin{ffcode}
940 | class Cart {
941 | private int total;
942 | void add(T i) {
943 | total += i.price();
944 | }
945 | }
946 | \end{ffcode}
947 |
948 | It may be represented in EO like this:
949 |
950 | \begin{ffcode}
951 | [] > cart
952 | memory 0 > total
953 | [i] > add
954 | total.write > @
955 | total.plus (i.price)
956 | \end{ffcode}
957 |
958 | As the example demonstrates, the presence of generics in class declaration may be ignored, since EO is a language without types and type checking.
959 |
960 | \subsection{C++ Templates}
961 | \label{sec:templates}
962 |
963 | Templates are a feature of the C++ programming language that allows functions and classes to operate with generic types, allowing a function or class to work on many different data types without being rewritten for each one.
964 |
965 | \begin{ffcode}
966 | template T max(T a, T b) {
967 | return a > b ? a : b;
968 | }
969 | int x = max(7, 42);
970 | \end{ffcode}
971 |
972 | It may be represented in EO like this:
973 |
974 | \begin{ffcode}
975 | [a b] > max
976 | if. > @
977 | a.gt b
978 | a
979 | b
980 | max 7 42 > x
981 | \end{ffcode}
982 |
983 | As the example demonstrates, the presence of templates may be ignored, since EO is a language without types and type checking.
984 |
985 | \subsection{Mixins}
986 | \label{sec:mixins}
987 |
988 | A mixin is a class that contains methods for use by other classes without having to be the parent class of those other classes. The following code demonstrates how Ruby module is included into a class:
989 |
990 | \begin{ffcode}
991 | module Timing
992 | def recent?
993 | @time - Time.now < 24 * 60 * 60
994 | end
995 | end
996 | def News
997 | include Timing
998 | def initialize(t)
999 | @time = t
1000 | end
1001 | end
1002 | n = News.new(Time.now)
1003 | n.recent?
1004 | \end{ffcode}
1005 |
1006 | This code may be represented in EO by just copying the method \ff{recent?} to the object \ff{News} as if it was defined there.
1007 |
1008 | \subsection{Annotations}
1009 | \label{sec:annotations}
1010 |
1011 | In Java, an annotation is a form of syntactic metadata that can be added to source code; classes, methods, variables, parameters and Java packages may be annotated. Later, annotations may be retrieved through Reflection API. For example, this program analyzes the annotation attached to the class of the provided object and changes the behavior depending on one of its attributes:
1012 |
1013 | \begin{ffcode}
1014 | interface Item {}
1015 | @Ship(true) class Book { /*..*/ }
1016 | @Ship(false) class Song { /*..*/ }
1017 | class Cart {
1018 | void add(Item i) {
1019 | /* add the item to the cart */
1020 | if (i.getClass()
1021 | .getAnnotation(Ship.class)
1022 | .value()) {
1023 | /* mark the cart as shippable */
1024 | }
1025 | }
1026 | }
1027 | \end{ffcode}
1028 |
1029 | The code may be represented in EO using classes suggested in Sec.~\ref{sec:classes}:
1030 |
1031 | \begin{ffcode}
1032 | [] > book
1033 | ship TRUE > a1
1034 | [] > new
1035 | [] > @
1036 | [] > song
1037 | ship FALSE > a1
1038 | [] > new
1039 | [] > @
1040 | [] > cart
1041 | [i] > add
1042 | # Add the item to the cart
1043 | if. > @
1044 | i.a1.value
1045 | # Mark the cart shippable
1046 | TRUE
1047 | FALSE
1048 | \end{ffcode}
1049 |
1050 | Annotations become attributes of objects, which represent classes in EO, as explained in Sec.~\ref{sec:classes}: \ff{book.a1} and \ff{song.a1}.
1051 |
1052 | \section{Traceability}
1053 |
1054 | Certain amount of semantic information may be lost during the translation from a more powerful programming language to EO objects, such as, for example, namings, line numbers, comments, etc. Moreover, it may be useful to have an ability to trace EO objects back to original language constructs, which they were motivated by. For example, a simple C function:
1055 |
1056 | \begin{ffcode}
1057 | int f(int x) {
1058 | return 42 / x;
1059 | }
1060 | \end{ffcode}
1061 |
1062 | It may be mapped to the following EO object:
1063 |
1064 | \begin{ffcode}
1065 | [x] > f
1066 | [] > @
1067 | "src/main.c:1-1" > source
1068 | 42.div x > @
1069 | "src/main.c:0-2" > source
1070 | \end{ffcode}
1071 |
1072 | Here, synthetic \ff{source} attribute represents the location in the source code file with the original C code. It's important to make sure during translation that the name \ff{source} doesn't conflict with a possibly similar name in the object.
1073 |
1074 | \section{Conclusion}
1075 |
1076 | We demonstrated how some language features often present in high-level object-oriented languages, such as Java or C++, may be expressed using objects. We used EO as a destination programming language because of its minimalistic semantics: it doesn't have any language features aside from objects and their composition and decoration mechanisms.
1077 |
1078 | \printbibliography
1079 |
1080 | \clearpage
1081 |
1082 | \end{document}
1083 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:base"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------