📜 ⬆️ ⬇️

Where is the type: right or left?

Once I saw another article on Habré, dedicated to a completely new and unexplored Go language for me, I decided to try what kind of animal it was and what it was eaten with (Mostly, of course, I liked the logo) . Of course, the language has many features and is quite convenient. But what immediately surprised me was the principle of variable declaration, which is different from C-like languages, namely, the type of variables is described to the right of the variable name. As a person who practically grew up in C, I was surprised. Then of course I remembered Pascal that there, too, the type of the variable was on the right. Being interested in this question, I tried to understand why one or another syntax for describing the type of variables in these 2 languages ​​is used.



We begin with a description of the syntax for declaring variables in C-like languages. In C, it was decided to abandon a separate syntax for describing variables and allow variables to be declared as expressions:

int x; 

As we can see, the type of the variable is on the left, then the name of the variable. Due to this, we maximally bring the declaration of the variable to the usual expression. Suppose this:
')
 int x = 5; 

Or this:

 int x = y*z; 

In principle, everything is simple and clear, and quite logical, let's look at the definition of functions in C.
Initially, C used the following function definition syntax:

 int main(argc, argv) int argc; char *argv[]; { /* ... */ } 

Variable types were not described together with the names of the arguments, but then the syntax was replaced with another one:

 int main(int argc, char *argv[]) { /* ... */ } 

Everything here is also quite simple and understandable. But this convenience begins to evaporate when pointers to functions and functions that can take pointers to them come into play.

 int (*fp)(int a, int b); 

Here fp is a reference to a function that takes 2 arguments and returns an int. In principle, it is not difficult, but what will happen if one of the arguments is a function reference:

 int (*fp)(int (*ff)(int x, int y), int b) 

Already somehow complicated or here is an example:

 int (*(*fp)(int (*)(int, int), int))(int, int) 

In it, to be honest, I got lost.
As can be seen from the description, when declaring function pointers in C languages, there is a significant drawback in the readability of the code. Now let's look at what method suggests using the variable definitions in C by David Anderson. Reading takes place according to the Clockwise / Spiral Rule method (clockwise / spiral).
This method has 3 rules:
  1. Reading begins with an unknown element in a spiral motion;
  2. Spiral expression processing continues until all characters are covered;
  3. Reading must begin with parentheses.

Example 1:



Following the rule, we start with an unknown str:

Take an example more complicated
Example 2:





So, without much effort, David Anderson suggests that we read the definition of variables.

Now let's look at the diametrically opposite syntax when the type of a variable is to the right of the variable name, using the example of Go.

In Go, variables are read from left to right and look like this:

 var x int var p *int var a [3]int 

There is no need to use any spiral methods, it is read simply
- the variable a is an array consisting of 3 elements of type int.
With functions, too, everything is quite simple:

 func main(argc int, argv []string) int 

And this announcement is also read with ease from left to right.

Even complex functions that accept other functions are readable from left to right:
 f func(func(int,int) int, int) int 

f is a function that takes a function, which, in turn, takes 2 integers in parameters and returns an integer, and an integer, and returns an integer.

These are the differences in the definition of variables in the languages ​​of the C and Go family. Obviously, Go clearly wins this. But if we now recall which languages ​​grew out of the good old C - this is C ++, C #, Java - they all use the definition of variables of this type. And they are built on OOP paradigms and do not use (or practically do not use) the transfer of pointers to functions, all of which have been replaced by classes for us. The drawbacks that come to light on the definition of the type of variable on the left evaporate when using OOP.

Source: https://habr.com/ru/post/270081/


All Articles