EPJ Web of Conferences 244, 01009 (2020) https://doi.org/10.1051/epjconf/202024401009 Complexity and Disorder Meetings 2018–2020

How Combinatory Logic Can Limit Computing Complexity

Hugolin Bergier1,∗ 1Regis University

Abstract. As computing capabilities are extending, the amount of source code to manage is inevitably becoming larger and more complex. No matter how hard we try, the bewildering complexity of the source code always ends up overwhelming its own creator, to the point of giving the appearance of chaos. As a solution to the cognitive complexity of source code, we are proposing to use the framework of Combinatory Logic to construct complex computational concepts that will provide a model of description of the code that is easy and intuitive to grasp. Combinatory Logic is already known as a model of computation but what we are proposing here is to use a logic of combinators and operators to reverse engineer more and more complex computational concept up from the source code. Through the two key notions of computational concept and abstract operator, we will show that this model offers a new, meaningful and simple way of expressing what the intricate code is about.

1 Introduction The point of this paper is to propose a solution to the overwhelming cognitive complexity of source code in In Sept. 26, 2017, an article entitled ”The Coming large applications. By cognitive complexity, we mean a Software Apocalypse” [1] exposed the dangers we’re fac- level of intricacy in the code that makes it too difficult to ing as software implementations are becoming increas- grasp for a human mind. ingly complex: ”Software has enabled us to make the most We are proposing to use the framework of Combina- intricate machines that have ever existed. And yet we have tory Logic to construct complex computational concepts hardly noticed, because all of that complexity is packed as a model of description of the source code that is easy into tiny silicon chips as millions and millions of lines of and intuitive to grasp. Combinatory Logic is already code. But just because we can’t see the complexity doesn’t known as a model of computation but what we are propos- mean that it has gone away (...) Just by editing the text in ing here is to use a logic of combinators and operators to a file somewhere, the same hunk of silicon can become reverse engineer more and more complex computational an autopilot or an inventory-control system. This flexi- concept up from the source code. This will lead to what bility is software’s miracle, and its curse. Because it can we can call a vertical simplification of the computational be changed cheaply, software is constantly changed; and concepts: through progressive layers of complexity, we because it’s unmoored from anything physical it tends to can define high-level concepts from other (less complex) grow without bound. The problem is that we are attempt- concepts without having to use the most primitive compu- ing to build systems that are beyond our ability to intellec- tational concepts, like incrementation or conditionals. To tually manage." the vertical simplification, we will add an horizontal sim- As computing capabilities are extending, the amount plification: given that a concept in Combinatory Logic is of source code to manage is inevitably becoming larger essentially the application of an operator to an operand, and more complex. No matter how hard we try, the be- we can use the combinators to extract a meaningful ab- wildering complexity of the source code always ends up stract computational operator that is simpler to grasp than overwhelming its own creator, to the point of giving the the complex concept it composes. appearance of chaos. Most applications source code has become intrinsically complex for a human being to read, 2 Applicative Languages and Combinatory navigate and comprehend. Logic One needs to step back from the source code in order to look at the big picture. What happens if a developer Combinatory Logic is an applicative language. While tries to step back from the code? Unlike Google Maps, the primitive notions of application, operator and operand zooming in and out on a program source code will radi- belong to applicative languages in general, the notion of cally change the cognitive complexity of the content. The combinator and β-reduction are specific to Combinatory big picture contains simply more data and intricacy than Logic. the small picture. Both the notions that belong to applicative languages in general and to Combinatory Logic in particular play an ∗e-mail: [email protected] important role in what follows.

© The Authors, published by EDP Sciences. This is an open access article distributed under the terms of the Creative Commons Attribution License 4.0 (http://creativecommons.org/licenses/by/4.0/). EPJ Web of Conferences 244, 01009 (2020) https://doi.org/10.1051/epjconf/202024401009 Complexity and Disorder Meetings 2018–2020

2.1 Applicative Languages

Applicative languages rely on the fundamental oper- Unlike ’>eval’ the relator ’=’ is both symmetrical and ation of applying an operator to an operand in order to static. Indeed, in set theory, the function is given as a set of dynamically produce a result. What distinguishes applica- ordered pairs < x, y > and any image y is coexisting with tive languages from set-theoretical languages is that the the corresponding argument x. application is considered as primitive notion and not as a The result of an application operation is not necessarily notion derivable from that of set. Applicative languages an operand as in the previous example. It can also be a new study operational processes : their construction, function- operator. This fundamental property of the application op- ing and nesting. By choosing to apprehend the applica- eration is called repeatability. An application operation tion of an operator to an operand as a primitive notion, we can produce a new operator which is in turn applicable to place ourselves in a logical framework different from that an operand. For example, the operation squared applied which is used in most modern logic systems. There are to plus-three produces the new plus-three-all-squared op- a variety of applicative languages: the lambda-calculus of eration. Repeatability is a very important characteristic of Church [2]; the combinatorial logic of Curry [3, 4] and applicative systems in our context because, as we men- F. Fitch [5]; the attempts of WVO Quine [6]. In Computer tioned above, we want to be able to understand complex Science, applicative languages correspond to a whole fam- computational concepts as related to other computational ily of programming languages called functional (among concepts, not directly to the actual implementation. which Lisp, Haskell and ML). After having presented the foundations of applicative systems, we will focus on Com- 2.2 Combinatory Logic binatory Logic. As we have just said, the primitive notion of an ap- 2.2.1 Combinators and reduction plicative system is a binary operation, called application. The first argument of the application is called an operator, Combinators are abstract operators that combine the the second argument is called an operand. The value of predefined operators of an application system so as to form this operation is called result or outcome. In an applica- new, more complex, operators. As operators, they are ap- tion operation, an operator f is applied to its operand a to plicable to their operands. The evaluation of a combinator produce the result b. We can simply represent the applica- application is called β-reduction. This evaluation defines tion as follows: the meaning of the combinator, regardless of any exter- f a nal interpretation. The meaning of a combinator is going We call this expression an applicative expression that we to depend on the way it combines its operands through can read “operator f applies to operand a”. When the op- β-reduction: permutation, duplication, composition, dele- eration of application is executed, a result b appears. Be- tion,... Thus, combinators are formal tools endowed with tween the application expression and the result, we intro- an intrinsic semantics [? ]. In other words, the semantics of combinators is not defined by an external interpretation duce a relation, designated by >eval ; we then have: in a model. Combinators are therefore very specific opera- f a >eval b tors in that they are completely reducible to their combina- torial action (that which is performed on their operands). which reads “the operator f applies to the operand a to give One could say that they belong to an additional level of ab- the result b. "The process of getting from operation to straction compared to the operators since their domain of result is called evaluation ; it is expressed by the relation interpretation is not given. Let us now introduce the most ’> ’. The evaluation is a non-symmetrical and dynamic eval common elementary combinators. relation: • Non-symmetrical because it is true that f and a deter- mine b but not the other way around. 2.2.2 Elementary combinators • Dynamic since there are two successive "moments": f a Combinatory Logic fits particularly well the frame- does not coexist with its result b but precedes it. work of Natural Deduction [7] which defines the syntactic Note that these two properties of the evaluation – that rules of formation of the language in same times as its for- the set-theoretic notion of function doesn’t have – are mal semantics through a series of rules of introduction and tightly related to the properties of code execution in com- rules of elimination of the logical operators. puter science. The execution of a program is nothing else Let us take the example of the combinator of compo- that the evaluation of a formal expression. In that re- sition B: spect, the applicative principle fits very well the computing framework. Rule of elimination [B-e]: Example 1. The application “squared” can be written: 1 Bxyz x(yz) B squared5 >eval (5)2 >eval 25 2 [ -e] In set theory, we have: This deduction corresponds to the β-reduction [3]:

squared(5) = (5)2 = 25 Bxyz ≥β x(yz)

2 EPJ Web of Conferences 244, 01009 (2020) https://doi.org/10.1051/epjconf/202024401009 Complexity and Disorder Meetings 2018–2020

Semantically, B can be interpreted as an operator Example 2. (combinator) that takes to functions (x and y in this case) 1 WBKxyz and compose them together to be applied to the third operand (z). The role played by B becomes more obvious 2 BKKxyz [W-e] if we take usual function names for the first two operands 3 K(Kx)yz [B-e] and if use the function notation: 4 Kxz [K-e]

B f gx ≥β f (g(x)) 5 x [K-e] Can be simplified as: If we abstract from x and use the usual notation for com- 1 WBKxyz position ’◦’, we have1 2 BKKxyz 3 K(Kx)yz B f g ≥β [ f ◦ g] 4 Kxz

Rule of introduction [B-i]: 5 x 1 x(yz) 2 Bxyz [B-i] 2.3 A Complexity Threshold Combinator of duplication W: Combinatory Logic is already known as a model of Rule of elimination [W-e]: computation but what we are proposing here is to use a 1 Wxy logic of combinators and operators to reverse engineer more and more complex computational concept up from 2 xyy [W-e] the source code. This will lead to what we can call a verti- Rule of introduction [W-i]: cal simplification of the computational concepts: through 1 xyy progressive layers of complexity, we can define high-level concepts from other (less complex) concepts. To the ver- 2 Wxy [W-i] tical simplification, we will add an horizontal simplifica- Given a rule of elimination of a combinator, the rule of tion: given that a concept in Combinatory Logic is es- introduction is straightforward. So we will only give the sentially the application of an operator to an operand, we latter for the following combinators. can use the elementary combinators to extract a meaning- Combinator of identity I: ful abstract computational operator that is simpler to grasp than the complex concept it composes. 1 Ix As we go through the process of building up complex 2 x [I-e] computational concepts out of simpler ones in the next section, we will explorer both ways of limiting the cog- Combinator of deletion K: nitive complexity with a particular focus on the vertical 1 Kxy simplification. We will explore the horizontal simplifica- tion in further details in Section 5. 2 y [K-e] Combinators of distribution: 1 Φxyzu 3 From Code to Higher-Level Concepts 2 x(yu)(zu) [Φ-e] This section describes the process of building up com- plex computational concepts in the framework of Combi- 1 Ψxyzu natory Logic. If we had to give a name to this formal ap- 2 x(yz)(yu) [Ψ-e] paratus, it would be something like computational logic of operators. Although the approach is formal, we will not Sxyz 1 give an exhaustive account of it, particularly on the pro- 2 xz(yz) [S-e] gramming side where so many variants are possible. How- ever, we will give the principles of this method for build- In what follows, the β-reductions and β-expansions al- ing computational concepts, illustrated with extensive ex- ways follow a leftmost-outmost reduction strategy so we amples that are aiming at: (1) showing how the method can omit to specify which combinator is introduced or works with enough detail to be able to apply it to a larger eliminated (See Example 2). domain ; (2) demonstrating how such computational con- cepts can considerably reduce the cognitive complexity of 1The brackets designate that we’re not using left associativity as it is a program, i.e. how this method can make a complex piece usually the case in Combinatory Logic. of code much easier to grasp.

3 EPJ Web of Conferences 244, 01009 (2020) https://doi.org/10.1051/epjconf/202024401009 Complexity and Disorder Meetings 2018–2020

3.1 Primitive Computational Concepts 3.2 Combination of Concepts

Primitive Computational Concepts are the most prim- We’re now going one level up in the layers of abstrac- itive operations of computation. Those will depend on tion, thus introducing the important role of the combina- the level of language we’re abstracting from. Typically tors with respect to our goal: organizing of the computa- for a programming language, primitive operations will be tional chaos. Combinators are operators that combine the arithmetic, boolean or memory operations such as addi- primitive computational concepts in a certain applicative tion, multiplication, negation, declaration or assignment. order to build more complex operations. One could look at multiplication as non-primitive because Let us give some examples based on the primitive op- built upon the more primitive concept of addition. Now, eration of incrementing. arguably, multiplication is not a complex notion for the human cognition. By complex notion, we do not mean the 3.2.1 Example 1: Repetition subjection notion but precisely the precise meaning that it is combining more primitive notions. Multiplication is Let us consider the following snippet of code imple- such a combination with respect to addition but it is not menting an operation of incrementation repeated twice: perceived as such by people educated in arithmetic. It is Example 5. truly perceived as a primitive notion. 1 x = 1 ; 2 x = x ++; 3 x = x ++; 3.1.1 Example: Incrementing To express the double application of the incrementa- Incrementation is undoubtedly a primitive notion of tion operation, we will need: computation2. • Let Inc the incrementing operation which can be im- the combinator of duplication W (to express the dupli- plemented as follow: cation of the same operation); • the combinator of composition B (to express the com- Example 3. position of the two operations). 1 x = x + 1 ; The double incrementation in Example 5 can be for- malized as Or: (Double Incrementation of 1) WB Inc 1 Example 4. Indeed we have the following natural deduction: 1 x ++; 1 WBInc1 BInc Inc The operator may be applied to natural number to yield 2 1 the following evaluations: 3 Inc(Inc1) Where the levels of abstraction can be interpreted as Inc 1 ≥eval 2 follows: • WB Inc 1 means “increment 1 twice”. In pseudo-code: Inc 2 ≥eval 3 1 x = 1 ; Inc is the abstract operation of incrementing. We could 2 x = x ++; also express this abstraction from the second example of 3 x = x ++; implementation above: • WB Inc means “increment twice”. In pseudo-code, we could represent the abstraction as G ≡ _ + +; 1 x = _ ; The operator Inc can be considered independently of 2 x = x ++; 3 x = x ++; any variable or constant: it just signifies "incrementing." As defined here, Inc is an primitive computational concept • WB means “apply twice”. In pseudo code, we could because it is defined independently of any other operator. have somehting like By itself, Inc is very easy to grasp. Naturally, it usually 1 x = _ ; doesn’t occur by itself. Incrementing is always used within 2 x = __ ( x ) ; a computational context, like a conditional or a loop for 3 x = __ ( x ) ; instance. The general interpretation of what "increment- ing" means in the application domain depends on how it Note that, as we go more and more into abstract opera- is combined with other primitive programming concepts. tors, it becomes harder to express the idea in source code Such combination is the topic of the next section. format. And this is precisely the point: abstracting from the source code to express computational operations via 2Often presented as the successor function in computational models. higher-level concepts.

4 EPJ Web of Conferences 244, 01009 (2020) https://doi.org/10.1051/epjconf/202024401009 Complexity and Disorder Meetings 2018–2020

Moreover, beside the fact that we are operating this 1 Not False move toward abstraction, the fact that Combinatory Logic 3 2 doesn’t contain any variables x or y to express concepts 2 [Not False ≡de f B C I (C K) K (C K)] makes the implementation-level representation of opera- 3 B B B C C I (C K) K (C K) tors more complicated because code is highly dependent on the use of variables. 4 B (B C) C I (C K) K (C K) 5 B C (C I) (C K) K (C K) 6 C (C I (C K)) K (C K) 3.2.2 Conditionals 7 C I (C K) (C K) K 8 I (C K) (C K) K

Incrementation can also be part of a conditional block: 9 C K (C K) K 10 K K (C K) Example 6. 11 K

12 [True ≡de f K] 1 x = 1 ; 2 i f (Boolean) then{ 13 True 3 x ++; 4 } So we have: 5 e l s e{ 6 x ++; NotTrue ≥β False 7 x ++; 8 } NotFalse ≥β True We can now define the computational operation in Ex- Booleans can be represented as the following combi- ample 6 as: nators: I Boolean Inc (WB Inc) 1

Assume that Boolean is True. We have the following True ≡ K de f deduction: False ≡de f CK 1 IBoolean Inc(WBInc)1 2 [Boolean ≡ True ≡ K] And the negation defined as de f 3 IKInc(WBInc)1

3 2 3 2 4 KInc(WBInc)1 Not ≡de f B C I FalseTrue ≡ B C I (C K) K 5 Inc1 Indeed we have Which formally represents the operation of increment- ing 1. While if, on the contrary, Boolean is False: 1 Not True 1 IBoolean Inc(WBInc)1 3 2 2 [Not True ≡de f B C I (C K) K K] 2 [Boolean ≡ False ≡de f CK] 3 B B B C C I (C K) K K 3 I (C K)Inc(WBInc)1 4 B (B C) C I (C K) K K Which 4 CKInc(WBInc)1 5 B C (C I) (C K) K K 5 K(WBInc)Inc1 6 C (C I (C K)) K K 6 WBInc1 7 C I (C K) K K formally represents the operation of incrementing 1 twice 8 I K (C K) K (see Section 3.2.1). We thus have obtained the expected behavior from Ex- 9 K (C K) K ample 6: if Boolean is true, increment 1, else increment 1 10 CK twice. We can now explore the meaning of the complex oper- 11 [False ≡ CK] de f ator of conditionals: 12 False • I Boolean Inc (WB Inc) 1 means “increment 1 once if And Boolean is true, twice otherwise”. In pseudo-code:

5 EPJ Web of Conferences 244, 01009 (2020) https://doi.org/10.1051/epjconf/202024401009 Complexity and Disorder Meetings 2018–2020

1 x = 1 ; 1 x = 1 ; 2 i f (Boolean) then{ 2 i f (Boolean) then{ 3 x ++; 3 x ++; 4 } 4 } 5 e l s e{ 5 e l s e{ 6 x ++; 6 x ++; 7 x ++; 7 x ++; 8 } 8 }

• I Boolean Inc (WB Inc) means “increment once if we can say that we’ve "zoomed out" in the sense that Boolean is true, twice otherwise”. In pseudo-code: the third snippet is clearly a superset of the second, and the

1 x = _ ; second of the first. Now, Can we say that the combinatorial 2 i f (Boolean) then{ representation of computational concepts allow us to keep 3 x ++; a constant level of cognitive complexity while zooming 4 } 5 e l s e{ out? 6 x ++; If we represent the second and third snippets as direct 7 x ++; combination of primitive computational concept, it will 8 } not appear so: • I Boolean means “apply first operand if Boolean is true, (Double Inc.) WB Inc second operand otherwise”. In pseudo-code: (Conditioned Repet. of Inc.) I Boolean Inc (WB Inc) The latter is clearly more complex than the former. Ac- 1 __; 2 i f (Boolean) then{ tually, as we monotonically increase the complexity of the 3 __; code by zooming out, so are we increasing the complexity 4 } of the corresponding combinatorial expression. To main- 5 e l s e{ tain a low level of complexity, we have to advantage of 6 __; 7 } the progressive construction of more and more complex operators by making sure that newly constructed complex While the concepts of incrementation and double in- concepts are named: crementation are easy to name, the concept incrementing- (Double Inc.) Inc2 ≡WB Inc once-if-Boolean-is-true-twice-otherwise is more complex (Conditioned Repet. of Inc.) I Boolean Inc (Inc2) to define as a unified notion. Although it is not impossi- Now the two have a comparable level of complexity. ble. One could consider that the concept of conditioned repetition of incrementation would be accurate, assuming that it is either one or two incrementations. Defining and naming the combined concept is a crucial step in the con- 3.4 Higher-level Concepts ceptualization of source code. As we move up in the layers of abstraction by defin- 3.3 Defining Complex Concepts ing and naming more and more complex operators built upon other (less complex) operators, we are able to keep We said earlier that the progressive abstraction form a reasonable and constant level of cognitive complexity the source code is crucial for the comprehension of the because the less complex operators correspond to well code. We’re now going to see that the key to get a pro- known and well defined high-level computational con- gressive abstraction from the source code is to establish cepts3. intermediary meaningful layers. Let us assume that we have built complex computation We just saw how we could combine primary computa- concepts all the way up to the followings: tional concepts to form more complex computational con- cepts. Naming and defining concepts is what makes it pos- • Sb: Bubble Sort sible to zoom out from the source code without increasing T the cognitive complexity. • F100: First element greater than 100 To see that more clearly, let us examine the examples we just looked at. We can defined the following higher-level computa- From the incrementation snippet... tional concept:

1 x = 1 ; 2 x = x ++; T Class100 ≡ B F100Sb ...to the double incrementation snippet

1 x = 1 ; What is the meaning of Class100? Let us β-reduce 2 x = x ++; Class100 applied to a random array of numbers, say tem- 3 x = x ++; peratures: Temp. ...to the conditioned repetition of incrementation snip- pet 3which may be related to the application domain or not.

6 EPJ Web of Conferences 244, 01009 (2020) https://doi.org/10.1051/epjconf/202024401009 Complexity and Disorder Meetings 2018–2020

1 Class100 Temp Note that by memory topology, we do not necessarily mean the actual physical memory location on a device but T 2 Class100 ≡ B F100 Sb any kind of location (virtual or physical). Obviously, the T encoding of those notions will depend on the encoding of 3 B F100 Sb Temp the program data structure. But, in general, if we refer T 4 F100 (Sb Temp) to the computational model of Turing machines, we can

5 TempS ≡ Sb Temp show that any incremental movement in a data structure can be reduced to scanning through a tape (array). The T 6 F100 TempS initial position and the movement are analogous to the base Class100 applied to Temp is β-reducible to applying case and inductive case in recursive functions. T F100 (i.e. looking for the first element greater than 100) Example 8. In Example 7, we have: to TempS, a sorted version of Temp. So Class100 can be interpreted as "find the first element greater than 100 in • The incremental movement M is "moving to the next the sorted version of Temp". In other words Class100 is cell in the array arrayTemp[]". It is represented in the a classifying operator that separates the temperatures into code by: two : those greater than 100 and the others. While (arrayTemp[i] < 100){ Here again, the definition of Class100 remains of very i:=i+1; low cognitive complexity because it rests upon the two } T other complex computation concepts Sb (sorting) and F100 (first element > 100). • The initial position P0 is "the first cell" and is repre- sented in the code by: 3.5 Using loops to create new concepts i := 0; While (arrayTemp[i] < 100){ So far, we have seen that any computational concept i:=i+1; is either a primitive computational concept (e.g. incre- } menting) or a complex computational concept recursively defined over combinators and primitive concepts. Loops, however, do not correspond to one nor the other. They cre- As we just said, Σ is a special operator that generates ate new customized concepts from primitive or complex primitive computational concepts by taking as its operands concepts with the use of a new loop operator Σ. a movement M and an initial position P0. In the code, Σ To handle the loop behaviors, we need a topological corresponds to the inductive application of the movement semantics: a semantics of space and of movement in that to the initial position. So the following applicative opera- space. Locations in that space are analogous to actual tion

physical memory locations in the machine. ΣMP0 Let us take the example of the computation concept T is a primitive computational concept and we can write: F100 (Section 3.4) which could be implemented as follows:

Example 7. T ≡de f ΣMP0 i := 0 ; T may be interpreted as the concept of "being in tem- While (arrayTemp[i] < 100){ pArray". In the application domain it means "being a tem- i := i +1; perature". T is a primitive computational concept5 in the } program. z := arrayTemp[i]; From this primitive concept, we can easily build more complex concepts by adding layer of determination. A loop-concept is a primitive computational concept Adding determination to a concept consists in increasing created within the program. its intension6 by adding new qualifying attributes to the Σ is a special operator that generates primitive compu- concept. For example, the determination "blue" can be 4 tational concepts by taking as its operands a movement added to the concept "car" to build the new concept "blue M and an initial position P0 in the memory topology: car". As the Logic of Port Royal [8] points out, adding • A position in memory is any defined location in a data determinations will always increase the intension of the structure, whether it is a cell in an array, a record in a concept and decrease its extension (there are less blue cars database, a field in a table or a line in a file. than there are cars). The operator of determination δ take as operands two • A movement is an incremental change of position in the concepts to form a new concept: the first operand adds data structure, like moving to the next/previous cell, to determination to the second one. the next record, line or field. 5Predicate 4More precisely, those primitive computational concepts are primitive 6The intension of a concept is its meaning. Increasing the intension computational predicates can be seen as "eniching" the concept.

7 EPJ Web of Conferences 244, 01009 (2020) https://doi.org/10.1051/epjconf/202024401009 Complexity and Disorder Meetings 2018–2020

Example 9. Using the δ operator we can add the deter- i := 0 ; mination blue to the concept of car: While (arrayTemp[i] != NULL){ if arrayTemp[i] > 100{ δ BlueCar array2.add(arrayTemp[i ]); } i := i +1; } Primitive loop concepts add determination through conditional within the loop block: first, through the loop The additional determination is given by the conditional guard; second, through the additional conditionals in the guard. Note that such a conditional in the loop block is loop block. In Example 7, determination is added through not going to select only the first greater than 100 (F100) but the loop guard itself: all the values greater than 100: A100. We thus have the following new complex concept: Example 10. In the following snippet of code AT ≡ A ( T) ≡ A T i := 0 ; 100 de f δ 100 δε 100 While (arrayTemp[i] 100){ The complex concept AT means "all the temperatures i := i +1; 100 greater than 100". } z := arrayTemp[i]; 4 Computational concepts and cognitive The guard is adding the determination "first greater than 100". complexity We’ve already hinted to the fact that the cognitive com- Let us call F100 the boolean concept associated with plexity of combinatorial computational concepts is close the while loop guard in Example 7. F100 means "the first greater than 100" (it doesn’t say the "first what") and is to invariant under increasing scope of source code (what represented in the code by: we’ve called "zooming out" from the source code), just While (arrayTemp[i] < 100){ like the complexity of a map doesn’t increase as the user zooms out of a certain place on Google Map. We already defined T the primitive loop concept. So With the capability to express loop computational con- we have cepts, we can now make this point more clear. T Suppose the following snippet of code: F100 ≡de f δ F100 T if Boolean then{ Meaning "From the temperature array" with the additional i := 0 ; determination "greater than 100", i.e "the first temperature While (arrayTemp[i] < 100){ greater than 100." We’ve now formally constructed, from i := i +1; the primitive loop concept T, the complex concept FT 100 } mentioned in Section 3.4. z := arrayTemp[i] The guard can add all kind of determination to z ++; the primitive loop concept but it can also add the empty z ++; concept determination δε ≡ I like in the following snippet: } e l s e { i := 0 ; i := 0 ; While (arrayTemp[i] != NULL){ While (arrayTemp[i] < 100){ i := i +1; i := i +1; } } z := arrayTemp[i] Assuming that NULL is the value of the first empty z ++; cell, the only complex concept here will be: } } 0 T ≡de f δ ε T ≡ T We can use the primitive concepts, loop concepts and When the loop guard is empty, the conditionals within combinators we’ve examined so far to define the corre- the loop block can generate more complex concepts sponding complex concept: 2 T T through additional determination. We will only show an (C1) X ≡de f I Boolean (Inc F100)(Inc F100) example here without getting into the details7. Consider Which can be expressed as "the conditioned double the following snippet of code with an empty determina- incrementation of the first temperature greater than 0." tion in the loop guard and a conditional inside the loop to This high-level computational concept X combines other check if the value is grater than 100: (less) complex concepts: T (C2.1) F100 ≡de f δF100T 7 2 See subsequent paper for more on loop concepts. (C2.2) Inc ≡de f WB Inc

8 EPJ Web of Conferences 244, 01009 (2020) https://doi.org/10.1051/epjconf/202024401009 Complexity and Disorder Meetings 2018–2020

(C3) T ≡de f ΣMP0 those concepts are simpler to grasp than the application of one to the other. The power of Combinatory Logic lies in the capac- 8 We can define a tree of computational concepts where ity of reorganizing the combination of operators (hence the root is the highest level and most complex concept (the the name) in order to build meaningful abstract opera- complete scope of the code) and the leafs are the primitive tors. Without the W and B combinators, WB Inc 1 would computational concepts as defined previously. Going up be expressed as Inc(Inc(1)). This latter expression cannot and down the tree corresponds to zooming in and zoom- separate the concept of incrementing from the concept of ing out on the source code. Just like on Google Map, the applying twice because the two are entangled. zooming in and out doesn’t mean an decrease or increase This powerful feature of combinatory logic will find in cognitive complexity. a better illustration in the complex computational concept As a matter of fact, each of the definition above (C , 1 X: C .1, C .2, C ) are of comparable level of cognitive com- 2 2 3 X ≡ I Boolean (Inc2 FT )(Inc FT ) plexity despite their different size of scope on the source de f 100 100 code. The combinatorial abstraction into computational As it is defined now, there is no much interest in ab- concepts is robust with respect to cognitive complexity. stracting... It would be just like reducing the scope of the code... We have the following β-expansion: 5 Abstract Computational Operators 2 T T 1 [X ≡de f I Boolean (Inc F100)(Inc F100)] We have said earlier (Section 2.3) that there are two 2 I Boolean (Inc2 FT )(Inc FT ) ways to reduce the cognitive complexity of a high-level 100 100 2 T concept expressed in Combinatory Logic that we can call 3 Φ (I Boolean) Inc IncF100 the vertical and horizontal way: 2 T 4 B Φ (I Boolean) Inc IncF100 2 • Define and name intermediary concepts that are con- 5 [X1 ≡de f B Φ (I Boolean) Inc Inc] tained in the complex concept; T 6 [X ≡de f X1F100] • Define and name abstract operators of this concept. We can now describe the complex concept X as the We’ve extensively looked at the vertical way in Sec- application of: tion 3. We’ve also briefly mentioned some aspects of the X1: "The conditioned doubling of the incrementation" second, as in the following: (meaning, incrementation is doubled only if Boolean is • WB Inc 1 means “increment 1 twice”. true) onto: • WB Inc means “increment twice”. FT : "The first temperature greater than 100." • WB means “apply twice”. 100

Although this is not a complex one, this small example Here again, X1 can be further abstracted if needed. can help us clarify what we mean by: defining and naming Note that, although we can now focus on X instead of abstract operators of a complex concept can reduce the 1 X (thanks to the combinators B and Φ), this is not a matter cognitive complexity of that concept. of zooming into a of the initial code. It truly is an Let us remember that a combinatorial expression is as- abstraction. In the source code, the abstract operator X suming left associativity and is, in essence, the application 1 could be represented as: of an operator to an operand. If we can divide a combi- natorial expression in two parts, we have now an abstract if Boolean then{ operator applied to an operand. Those two concepts might z := ____ be easier to grasp than the whole. This is, in some sense, z ++; a divide-and-conquer strategy for reducing the cognitive z ++; complexity of the expression. } As explained above WB Inc 1 contains the abstract op- e l s e { erator WB Inc which means “increment twice”. So we can z := ____ divide the complex computational concept into two parts: z ++; Increment Twice | 1. We simply need to understand "1" } and "increment twice" instead of the whole complex con- } cept. If WB Inc ("increment twice") is still too complex to grasp, we can divide it again into two part as the above abstraction suggests: Apply Twice | Increment. Each of Abstract computational operators shed a new light on the understanding of a complex computational concept as 8 Analogous to the computational tree in recursive theory [9]. Al- the application of a simpler operator to a simpler operand. though, those computational tree do not have the capacity to reduce mul- tiple levels of function because recursive functions don’t include combi- The Combinators make it possible to build the most simple nators. For example, S(S(S(0))) is irreducibly on 4 levels in the tree. and meaningful operator/operand separation.

9 EPJ Web of Conferences 244, 01009 (2020) https://doi.org/10.1051/epjconf/202024401009 Complexity and Disorder Meetings 2018–2020

6 Conclusion References

[1] S.b.J. Somers, The coming software apoca- lypse (2017), https://www.theatlantic. The starting point of this paper was to propose a solu- com/technology/archive/2017/09/ tion to the overwhelming cognitive complexity of source saving-the-world-from-code/540393/ code in large applications. By cognitive complexity, we [2] A. Church, Noûs 7, 24 (1973) mean a level of intricacy in the code that makes it very [3] H.B. Curry, R. Feys, W. Craig, Combinatory logic difficult to grasp for a human mind. (North-Holland Publishing Company, 1958) We have proposed to use the framework of Combina- [4] H. Curry, Outlines of a formalist philosophy of math- tory Logic for constructing complex computational con- ematics (North-Holland, 1970) cepts as a simple model of description of the source code [5] F.B. Fitch, Elements of combinatory logic (Yale Uni- of a program. By "simple model of description" we mean versity Press, 1974) a model of description that doesn’t increase in cognitive [6] W.V. Quine, Word and Object (M.I.T. Press, 1960) complexity as the complexity or size of the code increases. [7] D. Jean-Pierre, G. Gaëll, B. Sauzay, Logique combi- In this paper, we have given the foundations of this for- natoire et lambda-calcul: des logiques d’opérateurs mal method by defining the primary notions of primitive (Cépaduès-éditions, 2016) computational concepts, primitive loop concept, operation [8] A. Arnauld, P. Nicole, La logique ou L’art de penser of determination and complex computational concept. ... (1741) Through a series of examples, we have shown that the [9] P. Odifreddi, Classical theory. the theory applicative framework of Combinatory Logic allows for of functions and sets of natural numbers (1999) setting a complexity threshold by defining intermediary [10] H. Bergier, D. Jean-Pierre, M.D. Popelard, T.G. concepts that are contained in the more complex concepts. Pavel, A. Vaetus, L. Peridy, Ph.D. thesis (2016) As complex computational concepts are combined (using [11] D.J. P., Langages applicatifs, langues naturelles, et combinators) into even more complex concepts, the com- cognition (Hermès, 1990) plexity of the former doesn’t have to be included into the [12] F. Maribel, Models of computation: an introduction latter as it has been already ontologically defined. to theory (Springer, 2009) [13] D.S.O. KROENING, DECISION PROCEDURES: Finally, we have explored an alternative way of reduc- an algorithmic point of view (SPRINGER, 2019) ing the cognitive complexity of a computational concept: abstract computational operator. Using combinators and [14] M. Sipser, Introduction to the the fundamental idea that a complex computational con- (Thomson Course Technology, 2006) cept is the application of a simpler operator to a simpler [15] A. Vaetus, D. Jean-Pierre, Ph.D. thesis (2001) operand, we can now divide a complex concept into two [16] T. Biggerstaff, B. Mitbander, D. Webster, Proceed- simpler ones in order to better grasp the complex applica- ings of 15th International Conference on Software tion as a whole. Engineering (1993)

10