-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbook.tex
3078 lines (2566 loc) · 142 KB
/
book.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass[12pt]{book}
\usepackage[utf8]{inputenc}
\usepackage[tt=false, type1=true]{libertine}
\usepackage{lmodern}
\usepackage[nonumbers,novert,bold,noframes]{ffcode}
\usepackage{to-be-determined}
\usepackage{href-ul}
\usepackage{graphicx}
\title{\includegraphics[height=2in]{cactus.pdf} \\[1in] EOLANG Book}
\author{Joseph Afriyie Attakorah \and
Roman Korostinskiy \and
Vitaliy Korzun \and
Eugene Popov \and
Hadi Saleh \and
Sergey Zykov}
\begin{document}
\raggedbottom
\maketitle
\tableofcontents
\chapter{Introduction}
The first programming languages appeared relatively recently: various researchers indicate the 1920s, 1930s and even 1940s. Our task is not to establish the earliest language, but to identify the features of patterns in their development.
As you might expect, the first programming languages, like the first computers, were quite primitive and focused on numerical calculations. These were purely theoretical scientific calculations (primarily mathematical and physical), and applied problems, in particular in the field of military affairs. Programs written in early programming languages were linear sequences of elementary operations with registers in which data was stored.
It should be noted that early programming languages were optimized for the hardware architecture of the particular computer for which they were intended, and although they provided high computing efficiency, standardization was still a long way off. A program that was quite workable on one computer often could not be executed on another. Thus, the early programming languages depended significantly on what is called the computing environment, and roughly corresponded to modern machine code or assembly languages.
The 1950s were marked by the emergence of programming languages of the so-called "high level", in comparison with the previously considered predecessors, respectively called low-level languages. At the same time, the difference lies in increasing the efficiency of developers' work by abstracting or distracting from specific hardware parts. One instruction (operator) of a high language the level corresponded to a sequence of several low-level instructions, or commands. Based on the fact that the program, in fact, was a set of directives addressed to the computer, this approach to programming was called imperative.
Another feature of high-level languages was the ability to reuse previously written program blocks that perform certain actions, through their identification and subsequent access to them, for example, by name. Such blocks are called functions or procedures, and programming has become more orderly. In addition, with the advent of high-level languages, the dependence of implementation on hardware has significantly decreased. The price for this was the emergence of specialized programs that convert the instructions of the emerging languages into the codes of a particular machine, or translators, as well as some loss in the speed of calculations, which, however, was compensated by a significant gain in the speed of application development and the unification of program code. It is worth noting that the operators and keywords of the new programming languages were more meaningful than the faceless digital sequences of codes, which also provided an increase in the productivity of programmers.
Naturally, learning new programming languages required significant time and money, and the efficiency of implementation on the previous hardware capabilities decreased. However, these difficulties were temporary, and, as the practice of programming showed, many of the first high-level languages were so successfully implemented that they are actively used today. One such example is the Fortran language, which implements computational algorithms. Another example is the APL language, which transformed into BPL and then into C. The basic constructions of the latter have remained unchanged for several decades and are present, for example, in the C-sharp language. Examples of other programming languages are ALGOL, COBOL, Pascal, and Basic.
In the 1960s, a new approach to programming emerged, which still successfully competes with the imperative approach: the declarative approach. Its essence lies in the fact that the program is not a set of commands, but a description of the actions that need to be performed. This approach, as we will see later, is much simpler and more transparent formalized by mathematical means. Hence the fact that it is easier to check programs for errors (validation), as well as for compliance with a given technical specification (verification).
A high degree of abstraction is also an advantage of this approach. In fact, the programmer does not operate with a set of instructions, but with abstract concepts that can be quite generalized. At the initial stage of development, declarative programming languages found it difficult to compete with imperative ones due to objective difficulties in creating an effective implementation of translators. Programs ran slower, but they could solve more abstract problems with less effort.
One of the ways to develop a declarative style of programming was the functional approach that arose with the advent and development of the LISP language, with which the EO language discussed below is in many respects similar. A distinctive feature of this approach is the fact that any program written in such a language can be interpreted as a function with one or more arguments. This approach makes it possible to transparently model the text of programs by mathematical means, which means that it is very interesting from a theoretical point of view.
Complex programs with this approach are built by aggregation of functions. In this case, the text of the program is a function, some arguments of which can also be considered as functions. Thus, the reuse of code is reduced to calling the previously described function, the structure of which, unlike the procedure of the imperative language, is mathematically transparent. Moreover, the types of individual functions used in functional languages can be variable. Thus, it is possible to process heterogeneous data (for example, ordering list items in ascending order for integers, individual characters and strings), or polymorphism.
Another important advantage of implementing functional programming languages is the automated dynamic allocation of computer memory for data storage. At the same time, the programmer gets rid of the routine duty to control the data, and if necessary, can run the function of "garbage collection" - cleaning the memory from those data that the program no longer needs (usually this process is periodically initiated by the computer). Thus, when creating programs in functional languages, the developer of the programmer focuses on the field of research (subject area) and to a lesser extent cares about routine operations (ensuring the correct presentation of data from the point of view of the computer, "garbage collection", etc.).
Since function is a natural formalism for functional programming languages, the implementation of various aspects of programming related to functions is greatly simplified. In particular, it becomes intuitively transparent to write recursive functions, i.e. functions that call themselves as an argument.
In addition, it becomes natural to implement the processing of recursive data structures (for example, lists - basic elements, say, for the LISP family of languages, trees, etc.). By implementing a pattern mapping mechanism, languages such as ML and Haskellare very well applicable for character processing. Examples of functional programming languages in addition to the mentioned LISP, ML, Haskell are also SML, as well as F-sharp.
In the 1970s, another branch of declarative programming languages related to projects in the field of artificial intelligence, namely logical programming languages, arose. According to the logical approach to programming, a program is a set of rules or logical statements. In addition, logical cause-and-effect relationships are allowed in the program, in particular on the basis of an implication operation. Thus, logical programming languages are based on classical logic and are applicable to logical inference systems, in particular for so-called expert systems. Logical programming languages naturally formalize behavioral logic, and they are applicable to descriptions of decision-making rules, for example, in systems focused on supporting business processes.
An important advantage of the approach is a sufficiently high level of machine independence, as well as the possibility of rollbacks - a return to the previous sub-goal with a negative result of the analysis of one of the options in the process of finding a solution (say, the next move when playing chess), which eliminates the need to find a solution by a complete search of options and increases the efficiency of implementation.
One of the disadvantages of the logical approach in conceptual terms is the specificity of the class of problems to be solved. Another practical flaw is the difficulty of effective implementation for real-time decision-making, say for life support systems. The nonlinearity of the program structure is a common feature of the declarative approach and, strictly speaking, an original characteristic, not an objective drawback. Examples of logical programming languages include Prolog (the name comes from the words PROgramming in LOGic)andMercury.
An important step towards the improvement of programming languages was the emergence of an object-oriented approach to programming and a corresponding class of languages. Within the framework of this approach, the program is a description of objects, their properties (or attributes), aggregates (or classes), relations between them, methods their interactions and operations on objects (or methods). The undoubted advantage of this approach is the conceptual proximity to the subject area of arbitrary structure and purpose. The mechanism of inheritance of attributes and methods allows you to build derived concepts on the basis of basic ones and thus create models arbitrarily complex subject area with specified properties.
Another theoretically interesting and practically important property of the object-oriented approach is the support of the mechanism for processing events that change the attributes of objects and simulate their interaction in the subject area. Moving through the hierarchy of classes from more general concepts of the subject area to more specific (or from more complex to simpler) and vice versa, the programmer gets the ability to change the degree of abstraction or concreteness of the view of the real world it models.
The use of previously developed (perhaps other teams of programmers) libraries of objects and methods can significantly save labor costs in the production of software, especially typical. Objects, classes, and methods can be polymorphic, making the implemented software more flexible and versatile.
The complexity of adequate (consistent and complete) formalization of object theory gives rise to difficulties in testing and verification of the created software. Perhaps this circumstance is one of the most significant drawbacks of the object-oriented approach to programming.
The most famous example of an object-oriented programming language is C++, which developed from the imperative language C. The EO language discussed below also has certain features of object-oriented, as evidenced by its name (EO - Elegant Objects).
The development of the event-controlled concept of the object-oriented approach was the emergence in the 1990s of a whole class of programming languages, which were called scripting languages, or scripts.
Within the framework of this approach, the program is a set of possible data processing scenarios, the choice of which is initiated by the occurrence of an event (clicking on the mouse button, hitting the cursor in a particular position, changing the attributes of an object, overflowing the memory buffer, etc.). Events can be initiated by both the operating system (in particular, Windows) and the user.
The main advantages of the languages of this class are inherited from object-oriented programming languages. This is intuitive clarity of descriptions, proximity to the subject area, a high degree of abstraction, good portability. The extensive reusability of code is also inherited by scripting languages from object-oriented ancestors.
An essential positive feature of scripting languages is their compatibility with advanced tools for computer-aided design and rapid implementation of software, or the so-called CASE - (Computer-Aided Software Engineering) and RAD - (Rapid Application Development) tools. One of the most advanced tools for computer-aided design and application development is Microsoft Visual Studio .NET.
Naturally, along with the advantages of the object-oriented approach, scripting languages inherited a number of shortcomings. The latter primarily include the complexity of testing and verification of programs and the possibility of multiple side effects occurring during operation, manifested due to the complex nature of the interaction of objects and the environment, represented by interfaces. At the heart of the concept of the EO language is the potential minimization of these negative side effects. Examples of scripted programming languages are JavaScript and VBScript.
Another very important class of programming languages are parallel computing support languages. Programs written in these languages are a collection of descriptions of processes that can be executed both in reality simultaneously and in pseudo-parallel mode. In the latter case, the device, processing processes, operates in a time-sharing mode, allocating time to process the data coming from the processes as needed (and sometimes taking into account the sequence or priority of operations).
Parallel computing languages allow you to achieve a noticeable gain in efficiency when processing large amounts of information coming, for example, from simultaneously working users, or having a high intensity (such as video information or high-quality audio data).
Another very significant area of application of parallel computing languages is real-time systems, in which the user needs to receive a response from the system immediately after the request. Systems of this kind are responsible, in particular, for life support and responsible decision-making.
The reverse side of the advantages of the class of programming languages under consideration is the high cost of software development, and therefore, the development of relatively small programs for a wide (for example, household purposes) is often unprofitable.
Examples of programming languages that support parallel computing include Ada, Modula-2, and Oz.
So, we have covered the history and evolution of programming languages and the main approaches to the development of software systems. An attempt is made to classify languages and approaches to programming, as well as an analysis of the advantages and disadvantages inherent in certain approaches and languages. Note that the above classification should not be considered the only true and absolute, since programming languages are constantly evolving and improving, and recent shortcomings are eliminated with the advent of the necessary tools or theoretical justifications (such as phi-calculus).
\\
\\
Summing up, we briefly list the considered approaches to programming:
\begin{itemize}
\item early non-structural approaches;
\item structural or modular approach (the task is divided into subtasks, then into algorithms, their structural diagrams are drawn up and implementation occurs);
\item functional approach;
\item logical approach;
\item object-oriented approach;
\item mixed approach (some approaches can be combined);
\item component-oriented (the software project is considered as a set of components, this approach is adopted, in particular, in Oracle Java and Microsoft .NET);
\item a purely object approach (a mathematically ideal variant that has not yet been implemented practically, but certain fragments are conceptually presented in the EO language discussed below).
\end{itemize}
\chapter{Initial examples}
This chapter provides sample EO programs to help you understand the basics. Each example has an explanation and references to additional information.
\section{Hello, World!}
Here a simple "Hello, World" program:
\begin{ffcode}
+package sandbox
+alias stdout org.eolang.io.stdout
[args...] > app
stdout > @
"Hello, world!\n"
\end{ffcode}
To run your first program, set up EO Sandbox (\url{https://github.com/objectionary/sandbox}) by following its \ff{README.md}. After sandbox has been set up create new file \ff{app.eo} in \ff{eo/sandbox} folder, and enter the code above. Then run it:
\begin{ffcode}
./run.sh
\end{ffcode}
As a result "Hello, World!" will be printed to console. This simple code demonstrates several concepts of EO language. Let’s examine what happens in this program. First two lines:
\begin{ffcode}
+package sandbox
+alias stdout org.eolang.io.stdout
\end{ffcode}
declare \textit{meta} statements. Meta \ff{package} instructs the compiler to assign place all objects defined in the file into particular package. \ff{alias} meta tells that the name \ff{stdout} is an alias for object \ff{org.eolang.io.stdout}, which is external to the file. \ff{alias} meta is similar to \ff{import} statement in Java or C++. Section \ref{subsec:"+"-qualifier} provides more information about meta qualifier (\ff{+}) and metas. Next line:
\begin{ffcode}
[args...] > app
\end{ffcode}
defines an \textit{abstract object} called \ff{app} with variable number of arguments referenced as \ff{args}. Square brackets (\ff{[]}) define \textit{free attributes} of an object. Free attributes of an object doesn't have any concrete values assigned to them. In this example attribute \ff{args} (used to pass command line arguments) doesn't contain any actual value. The \ff{> app} part bounds the object definition to name \ff{app}. \textit{Abstraction} is explained in more details in section \ref{sec:abstracion}. Lines:
\begin{ffcode}
stdout > @
"Hello, world!\n"
\end{ffcode}
state that the attribute \ff{@} of the object is bound to the result of \textit{application} of the object \ff{stdout} with its first argument assigned with string \ff{"Hello, world!\n"}. Application always results in a copy of object with one or more free attributes assigned with concrete values. More on application will be explained in section \ref{sec:application}. Here vertical notation of application is used. Note the indentation which defines the scope of the statement in EO. The above two lines can be also rewritten using horizontal notation:
\begin{ffcode}
stdout "Hello, world!\n" > @
\end{ffcode}
Attribute \ff{@} has special meaning: it denotes that this object \textit{decorates} the one written before bound symbol (\ff{>}). In this example object \ff{app} (\textit{decorator}) decorates the result of application of object \ff{stdout} (\textit{decoratee}). More one decoration see section \ref{subsec:@-attr}.
When the program is executed, the \ff{app} object is \textit{dataized}, i.e. data is tried to be extracted. For decorator object the data is extracted from its decoratee. Hence the result will be \textit{dataization} of \ff{stdout} object, which prints the string into console. Dataizaton is discussed in section \ref{sec:dataization}. It is important to remember that each EO program must be ended with a new line without any symbols.
\section{Celsius To Fahrenheit Converter}
Here is example of Celsius to Fahrenheit Converter:
\begin{ffcode}
+package sandbox
+alias stdout org.eolang.io.stdout
+alias sprintf org.eolang.txt.sprintf
+alias text org.eolang.txt.text
[cels] > fahrenheit
plus. > @
times.
div.
cels
5.0
9.0
32.0
[args...] > app
as-float. > celsius
text
args.at 0
stdout > @
sprintf
"Celsius: %f\nFahrenheit: %f\n"
celsius
fahrenheit celsius
\end{ffcode}
This program converts the number of degrees Celsius to the number of degrees Fahrenheit.
Run the program with one command line argument — the number of degrees Celsius:
\begin{ffcode}
./run.sh 20
\end{ffcode}
The output will be the number of degrees Fahrenheit:
\begin{ffcode}
Celsius: 20.000000
Fahrenheit: 68.000000
\end{ffcode}
Let's see what's going on in the code. At the first lines:
\begin{ffcode}
+package sandbox
+alias stdout org.eolang.io.stdout
+alias sprintf org.eolang.txt.sprintf
+alias text org.eolang.txt.text
\end{ffcode}
new aliases are declared. They are used for \ff{org.eolang.txt.sprintf} and
\\
\ff{org.eolang.txt.text} objects. The following will explain how to use them. Line:
\begin{ffcode}
[cels] > fahrenheit
\end{ffcode}
defines an abstract object called \ff{fahrenheit}. This object has one free attribute \ff{cels} which is used to pass number of degrees Celsius. The following lines:
\begin{ffcode}
plus. > @
times.
div.
cels
5.0
9.0
32.0
\end{ffcode}
constitute the body of the abstract object \ff{fahrenheit}. Here \ff{cels} free attribute is used to calculate the final number of degrees Fahrenheit. Object \ff{fahrenheit} decorates result of this calculations, so it will be dataized as this result.
These lines use \textit{dot notation}. The dot notation is used to refer to the attributes of an object. For example, here \ff{float} \textit{data object} attributes such as \ff{plus}, \ff{times} and \ff{div} are used. Data objects and their attributes is discussed in chapter \ref{chapter:basics}.
Here \textit{inverse} dot notation is used. It can be written in one line:
\begin{ffcode}
((cells.div 5.0).times 9.0).plus 32.0 > @
\end{ffcode}
An \textit{inverse dot notation} is used in order to simplify the syntax. The identifier that goes after the dot is written first, the dot follows, and the next line contains the part that is supposed to stay before the dot. On the following lines:
\begin{ffcode}
as-float. > celsius
text
args.at 0
\end{ffcode}
command line arguments are handled. The \ff{args} object is an \textit{array} and contains command line arguments. The attribute \ff{at} is used to access array elements. More about arrays in section \ref{section:arrays}.
The command line arguments themselves inside the \ff{args} array are represented as a \textit{string} object. So here \ff{args.at 0} is the first argument represented as a string. The object \ff{text} decorates the string that is applied to it. This object provides some additional attributes for working with strings, in our example — \ff{as-float} attribute. This attribute converts \ff{text} object to a \ff{float} object. Strings and their attributes are discussed in section \ref{seciotn:string}.
The \ff{> celsius} part copies the result to a \textit{closed} object called \ff{celsius}. Closed object is an object without free attributes. The following lines:
\begin{ffcode}
stdout > @
sprintf
"Celsius: %f\nFahrenheit: %f\n"
celsius
fahrenheit celsius
\end{ffcode}
print the result to stdout. Here \ff{sprintf} object is used for formatted printing to a string. More about \ff{sprintf} object in section \ref{subsec:sprintf}.
\section{Factorial}
Here is an example of Factorial program:
\begin{ffcode}
+package sandbox
+alias stdout org.eolang.io.stdout
+alias sprintf org.eolang.txt.sprintf
+alias text org.eolang.txt.text
[n] > fact
if. > @
n.lt 1
1
times.
n
fact (n.minus 1)
[args...] > app
as-int. > n
text
args.at 0
stdout > @
sprintf
"%d! = %d\n"
n
fact n
\end{ffcode}
This program calculates factorial. Run the program with one command line argument — $n$:
\begin{ffcode}
./run.sh 5
\end{ffcode}
The output will be $n!$:
\begin{ffcode}
5! = 120
\end{ffcode}
Let's examine what happens in the \ff{fact} abstract object. Line:
\begin{ffcode}
[n] > fact
\end{ffcode}
defines this object. The following lines:
\begin{ffcode}
if. > @
n.lt 1
1
times.
n
fact (n.minus 1)
\end{ffcode}
constitute the body of the object \ff{fact}. This object will be dataized as a factorial of free attribute \ff{n}. Here \ff{if} attribute of \ff{bool} data object is occurred. This attribute works like \ff{if-else} statement in Java or C++. A condition is the base object of \ff{if} attribute. First free attribute of \ff{if} will be dataized if the condition is true, and the second if false. More information about \ff{bool} data object and its attributes discussed in section \ref{sec:bool-data-type}.
In this case, object \ff{n.lt 1} is the condition. \ff{lt} is an attribute of the \ff{int} data object. This attribute uses for comparison its base object with its free attribute. If the base object is less than the free attribute, the result will be \ff{TRUE}, otherwise \ff{FALSE}. In the lines:
\begin{ffcode}
times.
n
fact (n.minus 1)
\end{ffcode}
object \ff{fact} is dataized \textit{recursively}. So, object \ff{fact} calculates the factorial in the classical recursive way.
The rest of the code in this example is very similar to what was discussed earlier.
\section{Filter Array}
This program removes numbers that are less than or equals to \ff{3} from an array of integers:
\begin{ffcode}
+package sandbox
+alias stdout org.eolang.io.stdout
+alias sprintf org.eolang.txt.sprintf
+alias list org.eolang.collections.list
[lst] > filter-list
filtered. > @
lst
[elem]
gt. > @
elem
3
[args...] > app
list > lst
* 7 2 1 0 9 4 8 3 6 5
filter-list lst > new-lst
seq > @
each.
new-lst
[elem]
stdout > @
sprintf
"%d "
elem
stdout "\n"
TRUE
\end{ffcode}
Run this program with no command line arguments:
\begin{ffcode}
./run.sh
\end{ffcode}
The output will be:
\begin{ffcode}
7 9 4 8 6 5
\end{ffcode}
Let’s examine what happens in this program. At the lines:
\begin{ffcode}
+package sandbox
+alias stdout org.eolang.io.stdout
+alias sprintf org.eolang.txt.sprintf
+alias list org.eolang.collections.list
\end{ffcode}
new aliases are declared (\ff{org.eolang.collections.list}). The following will explain how to use them. Lines:
\begin{ffcode}
list > lst
* 7 2 1 0 9 4 8 3 6 5
\end{ffcode}
declares closed object \ff{lst}. Here the object \ff{* 7 2 1 0 9 4 8 3 6 5} is an array declared with the symbol \ff{*}. The object \ff{list} decorates the array that is applied to it. This object provides some additional attributes for working with arrays, they will be used later. For more examples with \ff{list} object see section \ref{subsec:additional-arrays}. At the next line:
\begin{ffcode}
filter-list lst > new-lst
\end{ffcode}
object \ff{lst} is applied to \ff{filter-list} and result copies to \ff{new-lst}. Object \ff{new-lst} will be filtered array. Let's see how this works. Lines:
\begin{ffcode}
[lst] > filter-list
filtered. > @
lst
[elem]
gt. > @
elem
3
\end{ffcode}
defines object \ff{filter-list}. This object have one free attribute - an array to be filtered. This array must be a \ff{list} object in order to use attributes of \ff{list}. Attribute \ff{filtered} of \ff{list} has one free attribute. This free attribute is an \textit{anonymous abstract object} that itself has a free attribute. Anonymous abstract object work like regular abstract object, but it don't have a name. Therefore, it can be bound with free attributes of another abstract object, as in this example. More information about \textit{anonymous abstraction} in section \ref{subsec:anonymous-abstracion}.
So the \ff{filtered} attribute applies each element of the list to that anonymous abstract object. If the result of this application is \ff{FALSE}, the element will be removed from the list. Eventually, the result will be a filtered list. In this example anonymous abstract object dataized as \ff{TRUE} if element of list is greater than \ff{3}. So the result will be a filtered list with only elements greater than \ff{3}.
When list is filtered, it need to be printed. At the lines:
\begin{ffcode}
seq > @
each.
new-lst
[elem]
stdout > @
sprintf
"%d "
elem
stdout "\n"
TRUE
\end{ffcode}
\ff{new-lst} is printed using \ff{each} attribute of \ff{list} object. Attribute \ff{each} of \ff{list} has one free attribute. This free attribute is an anonymous abstract object that itself has a free attribute. It works similar to \ff{filtered} attribute, but \ff{each} don't change its base \ff{list} object. Attribute \ff{each} only applies anonymous abstract object to each elements in base list and evaluate result. In this example it only prints each element of the \ff{new-lst}.
The \ff{seq} object is also used here. The \ff{seq} object uses for sequencing computations. This object has one free attribute \ff{steps} that may have an arbitrary number of steps that will be evaluated one by one, from the beginning to the end in the sequential order. The \ff{seq} object starts the dataization process for each of the objects bound to the \ff{steps} attribute of it. On dataization, the \ff{seq} object evaluates into the result of datazation of the last step. Therefore, in this case, we need to add \ff{TRUE} as the last step, because object \ff{app}, as whole program, need to be dataized as \ff{TRUE}. Otherwise, the execution of the program will be considered incorrect.
\section{Search Files}
Here is an example of program that can recursively find all files with \ff{.eo} extension in directory:
\begin{ffcode}
+package sandbox
+alias stdout org.eolang.io.stdout
+alias sprintf org.eolang.txt.sprintf
+alias regex org.eolang.txt.regex
+alias list org.eolang.collections.list
+alias dir org.eolang.fs.dir
[source-dir] > find-eo-files
filtered. > @
list
walk.
dir source-dir
"**/*"
[f]
and. > @
f.is-dir.not
matches.
compile.
regex
"/.*\\.eo$/"
f
[args...] > app
args.at 0 > source-dir
each. > @
find-eo-files
source-dir
[f]
stdout > @
sprintf
"file: %s\n"
f
\end{ffcode}
Run this program with one command line argument - path to the directory to be explored:
\begin{ffcode}
./run.sh /path/to/dir/
\end{ffcode}
The output will be list of \ff{.eo} files contained in specified directory:
\begin{ffcode}
file: /path/to/dir/1.eo
file: /path/to/dir/2.eo
file: /path/to/dir/subdir/3.eo
\end{ffcode}
Let’s examine what happens in this program. At the lines:
\begin{ffcode}
+package sandbox
+alias stdout org.eolang.io.stdout
+alias sprintf org.eolang.txt.sprintf
+alias regex org.eolang.txt.regex
+alias list org.eolang.collections.list
+alias dir org.eolang.fs.dir
\end{ffcode}
new aliases are declared (\ff{org.eolang.txt.regex} and \ff{org.eolang.fs.dir}). The following will explain how to use them. Lines:
\begin{ffcode}
[source-dir] > find-eo-files
filtered. > @
list
walk.
dir source-dir
"**/*"
[f]
and. > @
f.is-dir.not
matches.
compile.
regex
"/.*\\.eo$/"
f
\end{ffcode}
defines object \ff{find-eo-files}. This object has one free attribute \ff{source-dir} - path to the directory in which to search. It returns \ff{list} with files which names end with \ff{.eo}. Let's consider how does this object works. The following lines:
\begin{ffcode}
walk.
dir source-dir
"**/*"
\end{ffcode}
shows \ff{walk} attribute of object \ff{dir}. Object \ff{dir} has one free attribute - path to the directory. This object provides attributes for working with directories. Attribute \ff{walk} is one of them. This attribute recursively goes through all files in the directory using rule, that applied to it. In this example the rule is \ff{"**/*"}. Attribute \ff{walk} returns list of suitable files as an \ff{array}.
In this examples files array is applied to \ff{list} object and then \ff{filtered} attribute is called. Let's figure out what rules are used to filter this list of files. Lines:
\begin{ffcode}
[f]
and. > @
f.is-dir.not
matches.
compile.
regex
"/.*\\.eo$/"
f
\end{ffcode}
defines anonymous abstract object, that is applied to \ff{filtered} attribute. Here \ff{and} is an attribute of \ff{bool} data object. It represents logical conjunction. Data object \ff{bool} has other attributes for logical operations, such as \ff{or} (logical disjunction) and \ff{not} (logical negation). More information about \ff{bool} data object attributes discussed in section \ref{sec:bool-data-type}.
So here are two conditions. First condition:
\begin{ffcode}
f.is-dir.not
\end{ffcode}
means that file \ff{f} must to be not a directory. Attribute \ff{is-dir} of \ff{file} object evaluates as \ff{TRUE} if its base object is directory, and \ff{FALSE} otherwise. More information about files in EO in section \ref{sec:files}. Second condition:
\begin{ffcode}
matches.
compile.
regex
"/.*\\.eo$/"
f
\end{ffcode}
means that the \ff{f} filename must end with \ff{".eo"}. Let's figure out how it works. First of all \ff{"/.*\\.eo$/"} is a string with regular expression which specifies all lines ending with \ff{.eo}. The \ff{regex} object is used to process regular expressions and provides some attributes to work with them. It has one free attribute - a string representation of regex object, it starts and ends with slash (\ff{/}). Attribute \ff{compile} process regular expression of its base \ff{regex} object. Finally, attribute \ff{matches} check whether the string bounded to its free attribute satisfies the regular expression in the base \ff{regex} object. It evaluates as \ff{TRUE} if the string matches the regular expression, and \ff{FALSE} otherwise.
Thus, \ff{find-eo-files} object can find all \ff{.eo} files in provided directory. Lines:
\begin{ffcode}
each. > @
find-eo-files
source-dir
[f]
stdout > @
sprintf
"file: %s\n"
f
\end{ffcode}
prints paths to found files.
\chapter{Principles of the Language}
The basic principles that the EO programming language relies on: objects, attributes, and four elemental operations — abstraction, application, decoration, and dataization.
\section{Objects} \label{sec:objects}
Objects are a centric notion of the EO programming language. Essentially, an object is a set of attributes. An object connects with and links other objects through its attributes to compose a new concept that the object abstracts.
An abstract object is an object that has at least one free attribute (see \ref{subsec:free-bound-attr}).
This is an example of an abstract object:
\begin{ffcode}
[a b] > sum
a.plus b > @
a > leftOperand
b > rightOperand
\end{ffcode}
A closed object is an object whose all attributes are bound.
These are examples of closed objects:
\begin{ffcode}
sum 2 5 > closedCopyOfSum
\end{ffcode}
Application can turn an abstract object to a closed one
\begin{ffcode}
# Abstraction can declare closed objects
[] > zero
0 > @
"0" > stringValue
# Closed objects may have abstract attributes
[x] > plus
sum 0 x > @
# And closed attributes, too
[] > negfiles
-0 > @
$.plus 1 > plusOne
\end{ffcode}
\section{Attributes}
An attribute is a pair of a name and a value, where a value of an attribute is another object. That is because "Everything in EO is an object". Hence, for instance, an attribute name of an object person may be also referred to as plainly the object name of the object person.
\subsection{Free and Bound Attributes.} \label{subsec:free-bound-attr}
\catcode`\#=12\relax
\tbd{
TODO: #21 add an example of using free and bound attributes
}
Binding is an operation of associating an attribute's value with some object. An attribute may be bound to some object only once.
An attribute that is not bound to any object is named a free attribute. An attribute that has some object associated with its value is called a bound attribute.
Free attributes may be declared through the object abstraction only. Binding may be performed either during object declaration using the bind (\ff{>}) operator (see the \ref{sec:abstracion} section for more information) or through object copying (see the \ref{sec:application} section for details).
\subsection{Accessing Attributes. The Dot Notation}
There are no access modifiers in the EO programming language. All attributes of all objects are publicly visible and accessible. To access attributes of objects, the dot notation is used. The dot notation can be used to retrieve values of attributes and not to bind attributes with objects.
\subsubsection{Examples}
The Horizontal Dot Notation
\begin{ffcode}
(5.plus 7).times 10 > calc
\end{ffcode}
The Vertical Dot Notation
\begin{ffcode}
times. > calc
plus.
5
7
10
\end{ffcode}
Here, \ff{plus} is an attribute of the object \ff{5} and \ff{times} is an attribute of the attribute object \ff{plus} (or, more precisely, an attribute of an object that \ff{plus} abstracts or dataizes to, which is an integer number \ff{int}).
\subsection{The \texttt{\$} locator}
Locator points to the place where to find an attribute. The \ff{$} character is reserved for the special locator self that every object has. The \ff{$} locator is used to refer to the object itself.
The \ff{$} locator may be useful to use the result of the object's dataization process for declaring other object's attributes.
The \ff{$} locator may be used to access attributes of an object inside of the object with the dot notation (e.g., \ff{$.attrA}), but this notation is redundant.
\subsection{The \texttt{@} attribute} \label{subsec:@-attr}
The \ff{@} attribute is named phi (after the Greek letter $\varphi$). The \ff{@} character is reserved for the phi attribute and cannot be used for any other purpose. Every object has its own and only \ff{@} attribute. The \ff{@} attribute can be bound to a value only once.
The \ff{@} attribute is used for decorating objects. An object bound to the \ff{@} attribute is referred to as a decoratee (i.e., an object that is being decorated) while the base object of the \ff{@} attribute is a decorator (i.e., an object that decorates the decoratee). Since the \ff{@} attribute may be bound only once, every object may have only one decoratee object. More on the decoration see in this section.
Besides, the \ff{@} attribute is heavily used in the dataization process (see this section for more information).
\subsection{The \texttt{\^} attribute}
The \ff{^} is used to refer to the parent object.
The \ff{^} attribute may be used to access attributes of a parent object inside of the current object with the dot notation (e.g., \ff{^.attrA}).
Example
\begin{ffcode}
[] > parentObject
42 > magicNumber
[] > childObject
24 > magicNumber
plus. > @
^.magicNumber
magicNumber
\end{ffcode}
Here \ff{^.magicNumber} refers to the \ff{parentObject} object's attribute and \ff{magicNumber} refers to \ff{childObject} object's attribute
\subsection{The \texttt{\&} attribute}
An instance of an abstact object (see the section \ref{sec:abstracion} section) may need to have access to the
object where the abstract was defined. Here is an example of it:
\begin{ffcode}
[] > parentObject
[f] > childObject1
f 10 > @
[f] > childObject2
^.childObject1 > @
[x]
&.f.plus x > @
\end{ffcode}
The objects \ff{childObject1} and \ff{childObject2} has one free attribute \ff{f}. The object \ff{childObject2} decorates \ff{childObject1} to which an anonymous object (see \ref{subsec:anonymous-abstracion}) with one free attribute \ff{x} is applied. The anonymous inner abstract object has to get access to the attribute \ff{f} of \ff{childObject2}. However, \ff{^.f} won't work, because the parent of it is a copy of \ff{childObject1}, and the parent of \ff{childObject1} is the object \ff{parentObject}. Thus, there is no way to get access to \ff{childObject1.f} using parent attributes.
The \textit{home} attribute \ff{&} helps here. Once an anonymous inner abstract object is created, its home attribute is set to the \ff{childObject2}. Its parent attribute \ff{^} is also set to the object \ff{childObject2}, but is later changed by the \ff{childObject1} when a copy of it is being made. However, the home attribute remains the same.
\subsection{The \texttt{<} attribute}
Each object has a special attribute \ff{<}, which is an integer refering to a unique identifier of an object in the entire runtime scope of a program. All of the following expressions are true:
\begin{ffcode}
TRUE.<.eq (TRUE.<)
42.<.eq (42.<)
plus.<.eq (plus.<)
\end{ffcode}
All of the following expressions are false:
\begin{ffcode}
42.<.eq (7.<)
(2.plus 2).<.eq (4.<)
(* 1 2).<.eq ((* 1 2).<)
\end{ffcode}
See \ref{subsubsec:comp-attrs} to find out about \ff{eq} attribute of \ff{int} type object.
\section{Abstraction} \label{sec:abstracion}
Abstraction is the operation of declaring a new object. Abstraction allows declaring both abstract and closed, anonymous and named objects.
If we are to compare abstraction and application, we can conclude that abstraction allows broadening the field of concepts (objects) by declaring new objects. Application allows enriching the objects declared through abstraction by defining the actual links between the concepts.
\subsection{Syntax}
The abstraction syntax includes the following elements:
\begin{enumerate}
\item (\textit{optional}) One or more comment lines before (e.g., \ff{# comment}).
\item A sequence of free attributes in square brackets. The sequence may be:
\begin{enumerate}
\item Empty (\ff{[]}). In this case, the declared object has no free attributes.
\item Containing one or more attribute names (\ff{[a]} or \ff{[a b c d e]}). In this case, the listed attribute names are the free attributes of the declared object.
\item Containing a variable-length (see \ref{subsec:"..."-qualifier}) attribute (\ff{[animals...]}). The attribute must be at the end of the list of attributes to work properly. Internally, this attribute is represented by the array object.
\end{enumerate}
\item \label{item:2.3.1.3} (\textit{optional}) Binding to a name ( \ff{> myObject}). Declared objects may be anonymous. However, anonymous objects must be used in application only (i.e., we can only supply anonymous objects for binding them to free attributes during application).
\item (\textit{optional}) The object may be declared as constant (i.e., dataized only once), if the object is bound to a name (see \ref{item:2.3.1.3}). For this, the \ff{!} qualifier (see \ref{subsec:"!"-qualifier}) is used.
\item (\textit{optional}) The object may be declared as an atom (i.e., its implementation is made out of the EO language (for instance, in Java)) if the object is bound to a name (see \ref{item:2.3.1.3}). For this, the \ff{/} qualifier (see \ref{subsec:"/"-qualifier}) is used (for example, \ff{/bool}).
\end{enumerate}
\subsection{Anonymous Abstraction} \label{subsec:anonymous-abstracion}
There are two types of anonymous abstraction: inline and plain multi-line. Here is example of plain multi-line anonymous abstraction:
\begin{ffcode}
[a b]
a.plus b > @
\end{ffcode}
The same can be expressed in just one line. Here is example of inline anonymous abstraction:
\begin{ffcode}
[a b] (a.plus b > @)
\end{ffcode}
\subsubsection{More Examples}
No free attributes abstraction
\begin{ffcode}
[] > magicalObject
42 > magicalNumber
# here we use abstraction to define
# an attribute
[a] > addSomeMagic
magicalNumber.plus a > @
\end{ffcode}
Variable-length attribute abstraction
\begin{ffcode}
[args...] > app
stdout > @
sprintf
"\n%d\n%d\n"
args.at 0
magicalObject.magicalNumber.plus a
\end{ffcode}
Anonymous abstraction
\begin{ffcode}
[args...] > app
reduced. > sum
list args
0
# this is anonymous abstraction
[accumulator current]
plus. > @
accumulator
(text current).as-int
\end{ffcode}
Inline anonymous abstraction
\begin{ffcode}
[args...] > app
reduce. > sum
list args
0
# abstraction
[accumulator current] (accumulator.plus (text current).as-int > @)
\end{ffcode}
\section{Application} \label{sec:application}
Application is the operation of copying an object previously declared with abstraction optionally binding all or part of its free attributes to some objects.
If we are to compare abstraction and application, we can conclude that abstraction allows broadening the field of concepts (objects) by declaring new objects. Application produces more concrete and specific copies of objects declared through abstraction by defining the actual links between the concepts by binding their free attributes.
\subsection{Syntax}
The application syntax is quite wide, so let's point out the constituents to perform the application:
\begin{enumerate}
\item An object being applied/copied.
\begin{enumerate}
\item It may be any existing (i.e., previously declared) object of any form — abstract, closed, anonymous, or named.
\item It may be also an attribute object. In this case, both horizontal and vertical dot notations can be used to access that attribute object.
\end{enumerate}
\item A sequence of objects to bind to the free attributes of the applied object. The sequence may be placed in-line (horizontally) or vertically, one indentation level deeper relatively the copied object level. The sequence may be:
\begin{enumerate}
\item \textit{Empty}. In this case, the applied object will stay abstract or closed, as it was before.
\item \textit{Containing one or more objects}. In this case, the listed objects will be bound to the free attributes of the applied object in their order of appearance.
\item \textit{Containing one or more objects with names after each} (like \ff{1:a} \ff{5:b} \ff{9:c}). In this case, the listed objects will be bound to the corresponding free attributes of the applied object (see \ref{subsec:":"-qualifier}).
\end{enumerate}
\item \label{item:2.4.1.3} (\textit{optiona}l) Binding to a name ( \ff{> myObject}).
\item (\textit{optional}) The object may be declared as constant (i.e., dataized only once), if the object is bound to a name (see \ref{item:2.3.1.3}). For this, the \ff{!} qualifier (see \ref{subsec:"!"-qualifier}) is used.
\end{enumerate}
\subsubsection{Examples}
Here application with no binding
\begin{ffcode}
42 > magicalNumber
\end{ffcode}
Horizontal application of the plus attribute of the magicalNumber
\begin{ffcode}
magicalNumber.plus 1 > secondMagicalNumber
\end{ffcode}
Vertical application \& application inside application
\begin{ffcode}
minus. > esotericNumericalEssence
times.
plus.
magicalNumber
22
17
10
\end{ffcode}
\subsection{Partial Application}
Essentially, application is used to bind free attributes of abstract objects to make their concrete and more specific copies. Application allows binding arbitrary number of free attributes, which can be used to partially apply objects.
\begin{ffcode}
# abstract object
[a b] > sum
a.plus b > @
\end{ffcode}
We can partially apply it to create a new, more specific concept:
\begin{ffcode}
sum > addTen
10:a
addTen > twenty
10:b
\end{ffcode}
\section{Decoration} \label{sec:decoration}
Decoration is the operation of extending one object's (the decoratee) attributes with attributes of the other object (the decorator). Through decoration, the decorator fetches all the attributes of the decoratee and adds up new own attributes. Hence, the decorator represents the decoratee with some extension in the functionality.
Syntax
The decorator's \ff{@} attribute should be bound to the decoratee object in order to perform the decoration operation.
The syntax for the decoration operation is as follows:
\begin{ffcode}
[] > theDecorator
theDecoratee > @
\end{ffcode}
Here, \ff{theDecorator} can access all the attributes of \ff{theDecoratee} and use them to define its own attributes.
Say, we have the purchase object that represents a purchase of some item that has a name, cost, and quantity. The \ff{purchaseTotal} decorates it and adds new functionality of calculating the total.
\begin{ffcode}
[itemName itemCost itemQuantity] > purchase
itemName > @
[] > purchaseTotal
purchase > @
times. > total
@.itemCost
@.itemQuantity
\end{ffcode}
Now we can access all attributes of purchase and \ff{purchaseTotal} through a copy of \ff{purchaseTotal}.
\section{Qualifiers}
In EO qualifiers are special symbols for modifying objects. They can change the behavior of the objects they apply to.
\subsection{The \texttt{:} Qualifier} \label{subsec:":"-qualifier}
The \ff{:} qualifier may be used to denote the exact name of the free attribute to be bound to the provided argument. It's easier to understand with an example:
\\
\\
We have a point in 3D space:
\begin{ffcode}
[x y z] > point
\end{ffcode}
We can make an application like we did before:
\begin{ffcode}
point
1
2
3
\end{ffcode}
But we also can use \ff{:} qualifier and denote the exact name of the free attributes:
\begin{ffcode}
point
3:z
1:x
2:y
\end{ffcode}
The second notation is equivalent to the first one. The only difference is that when we use the \ff{:} qualifier, we don't have to respect the order of the free attributes.
\subsection{The \texttt{...} Qualifier} \label{subsec:"..."-qualifier}
The \ff{...} qualifier is used to denote a varargs. The last free attribute in an abstract object may be a vararg, meaning that any number or zero arguments may be provided. All of them will be packaged in an array by the compiler, for example:
\begin{ffcode}
[x...] > sum |$\label{ln:sum-def}$|
sum 8 13 -9 |$\label{ln:sum-instance}$|
\end{ffcode}
Here, at the first line the abstract object \ff{sum} is defined with a free vararg attribute \ff{x}. At the second line a copy of the abstract object is made with three arguments. The internals of the \ff{sum} will see \ff{x} as an \ff{array} with three elements inside.
\\
\\
It is possible to provide an array as a parameter for vararg attribute (both variants are semantically equivalent):
\begin{ffcode}
* 42 7 > a
sum ...a
sum 42 7
\end{ffcode}
\subsection{The \texttt{`} Qualifier} \label{subsec:"`"-qualifier}
The \ff{`} qualifier used to make a copy of an object without giving any parameters to it. Here is an example of using \ff{`} qualifier:
\begin{ffcode}
point' > p
p 3 5 6 > p1
\end{ffcode}
Here, two objects will be created, \ff{p} and \ff{p1}, where the former is an abstract one, a copy of \ff{point}, while the later is a closed one with two parameters specified.
\subsection{The \texttt{!} Qualifier} \label{subsec:"!"-qualifier}
The \ff{!} qualifier is used to make the object it applies to a constant. EO is a declarative language with lazy evaluations. This means that this code would read the input stream two times:
\begin{ffcode}
[] > hello
stdout > say
sprintf
"The length of %s is %d"
stdin.next-line > x!
x.length
\end{ffcode}
The \ff{sprintf} object (see \ref{subsec:sprintf}) will go to the \ff{x} two times. First time, in order to use it as a substitute for \ff{%s} and the second time for \ff{%d}. There will be two round-trips to the standard input stream, which obviously is not correct. The \ff{!} qualifier at the \ff{x!} solves the problem, making the object by the name \ff{x} a \textit{constant}. This means that all attributes of \ff{x} are \textit{cached}. Important to notice that the cache is \textit{not deep}: the attributes of attributes are not cached.
Here, \ff{x} is an attribute of the object \ff{hello}, even though it is not defined as explicitly as \ff{say}. Anywhere a new name shows up after the \ff{>} symbol, it is a declaration of a new attribute in the nearest object abstraction.
\subsection{The \texttt{+} Qualifier} \label{subsec:"+"-qualifier}
The \ff{+} qualifier is called a meta qualifier and is used for meta statements. Meta statements are passed to the compiler and their meaning is compiler dependent and may differ between target platforms. You can see a case of using meta statements in the example below:
\begin{ffcode}
+package org.example
+alias org.eolang.io.stdout
[args...] > app
stdout > @
"Hello, world!\n"
\end{ffcode}
This program instructs the compiler to put all objects from the file into the package \ff{org.example} and helps it resolve the name \ff{stdout} (see \ref{subsec:stdout}), which is external to the file.
\subsection{The \texttt{/} Qualifier} \label{subsec:"/"-qualifier}
Some objects in EO programs may need to be platform specific and can't be composed from other existing objects---they are called \textit{atoms}.
For example \ff{stdout} (see \ref{subsec:stdout}) is an atom. Its implementation would be provided by the runtime. This is how the object may be defined:
\begin{ffcode}
+rt jvm org.eolang:eo-runtime:0.7.0
+rt ruby eolang:0.1.0
[text] > stdout /bool
\end{ffcode}
The \ff{/bool} suffix informs the compiler that this object must
not be compiled from EO to the target language. The object
with this suffix already exists in the target language and most
probably could be found in the library specified by the \ff{rt}
meta. The exact library to import has to be selected by the compiler. In the example above, there are two libraries specified: for JVM and for Ruby.
The \ff{bool} part after the \ff{/} qualifier is the name of object, which \ff{stdout} decorates. The name may be replaced by a question mark, if uncertain about the object being decorated. Atoms in EO are similar to native methods in Java and extern methods in C\#: this mechanism is also known as foreign function interface (FFI).
\section{Dataization} \label{sec:dataization}
Dataization is the operation of evaluation of data laying behind an object. The dataization process (denoted hereby as $D(something)$) is recursive and consists of the following steps:
\begin{enumerate}
\item $D(obj) = obj$ if $obj$ is a data object. Data objects are \ff{int}, \ff{float}, \ff{string}, \ff{char}, \ff{bytes}.
\item If the obj is an atom (atoms are objects that are implemented outside EO), then $D(obj)$ is the data returned by the code behind the atom.
\item Otherwise, $D(obj) = D(obj.@)$. That is, if the object is neither data nor an atom, then the object "asks" its decoratee to find the data behind it.
\end{enumerate}
It is important to note that if the \ff{@} attribute of the object (or any underlying object in the dataization recursive evaluation tree) is absent (free), then the dataization will fail.
If we want to dataize the object \ff{x}, all objects and attributes that are used in the definition of the \ff{@} attribute of the \ff{x} will be dataized. Like this, if we want to dataize the attribute \ff{x.attr}, all objects and attributes that are used in the definition of its \ff{@} attribute will be dataized.
The opposite is true. If the attribute \ff{x.attr} or the object \ff{x} itself are not used in the declaration of \ff{y}, then $D(y)$ will not dataize them and they will not be evaluated and executed. Thus, the dataization operation may be referred to as the lazy object evaluation (i.e., EO dataizes objects only when this is needed).
\section{EO syntax}
\catcode`\#=12\relax
\tbd{
TODO: #11 make an up-to-date version of the syntax
}
\begin{figure*}[ht]
\centering
\includegraphics[width=1\textwidth,]{EOsyntxax.jpg}
\caption{EO syntax}
\label{fig:uml1}
\end{figure*}
\chapter{Basics} \label{chapter:basics}
\section{Data Objects}
The EO Programming Language and The EO Standard Object Collection defines these data objects: \ff{bytes}, \ff{bool}, \ff{int}, \ff{float}, \ff{string}. All of them have \ff{as-bytes} attribute, which is an abstraction of their representation as a sequence of bytes.
All primitives also have \ff{as-hash} attribute, which, being an \ff{int}, is their own implementation of a hash function. They also have \ff{eq} attribute, which is \ff{TRUE} if the primitive is equal to another object, through the use of \ff{ˆ.as-bytes.eq}
\section{bytes Data Object}
The \ff{bytes} data object represents an abstraction of an sequence of bytes and can be empty or contain an theoretically unlimited number of bytes.
Fully Qualified Name: \ff{org.eolang.bytes} (no aliasing or FQN reference required since the object is automatically imported).
\subsection{Syntax}
The \ff{bytes} data object may be parsed by the EO compiler directly from the source code. The syntax rules for \ff{bytes} values are as follows.
EBNF Notation:
\begin{ffcode}
BYTES ::= BYTE ( ‘-’ BYTE ) | ‘--’
BYTE ::= [0-9A-F][0-9A-F]
\end{ffcode}
Example:
\begin{ffcode}
+package sandbox
+alias stdout org.eolang.io.stdout
+alias sprintf org.eolang.txt.sprintf
[args...] > app
stdout > @
sprintf
"%d\n"
FF-FF-FF-FF-FF-FF-FF-FF.as-int
\end{ffcode}
\textbf{Output}
\begin{ffcode}
IN$: ./run.sh
OUT>: -1
IN$:
\end{ffcode}
\subsection{bytes Attributes}
\subsubsection{as-\textit{type} Attribute}
The object \ff{bytes} has these four attributes, to turn itself into one of four primitive data objects: \ff{as-int}, \ff{as-bool}, \ff{as-float}, and \ff{as-string}.
The attribute \ff{as-int} expects the size of the sequence to be less or equal to eight. The attribute \ff{as-bool} is \ff{FALSE} only if all bytes equal to zero. The attribute \ff{as-float} expects exactly eight bytes.
Here is an example of using these attributes:
\begin{ffcode}
+package sandbox
+alias stdout org.eolang.io.stdout
+alias org.eolang.txt.sprintf
[args...] > app
stdout > @
sprintf
"%d\n%b\n%f\n%s\n"
FF-FF-FF-FF-FF-FF-FF-FF.as-int
00-.as-bool
3F-80-00-00-00-00-00-00.as-float
41-.as-string
\end{ffcode}
\textbf{Output}
\begin{ffcode}
IN$: ./run.sh