├── .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 | [![arXiv](https://img.shields.io/badge/arXiv-2112.11988-green.svg)](https://arxiv.org/abs/2112.11988) 4 | [![make](https://github.com/yegor256/reducing-programs-to-objects/actions/workflows/latexmk.yml/badge.svg)](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 | --------------------------------------------------------------------------------