Hello! Not so long ago, I decided to run a gallop on different programming languages. I at least fluently looked at examples on each of them, researched Wikipedia and other blogs. What for? Probably purely out of curiosity, because I didn’t discover anything fundamentally new for myself. So, closer to the topic. In many modern (and not so) languages, more or less standard constructions are used, such as
if ,
while or
case . But in some languages these constructions, although present, have amazing properties and abilities. Below I will consider only those concepts of programming languages that exist in other languages, only in a modified form. I will not consider unique and unique concepts. Also, I will mainly consider rare or dead languages. Who cares, welcome under the cat!
BETA
BETA is an object-oriented language, the successor of Simula. It has a number of amazing features that I will consider. If anything, there is
an article on Wikipedia. So, in BETA there are only two (!) Control constructs: if and for. And this is quite enough for life. The if construct is remarkable in that it allows you to write the result of an expression before each then, which is located after the if. Not only does this allow you to get rid of the else branch, so this approach makes it possible to simulate a case construct:
(if x
// 17 then …
// 33 then …
// y+3 then …
else …
if);
(if (x>0) and (y<0)
// True then …
// False then …
if)
What to say, amazing language! The entire syntax can be briefly described on one
page . BETA is also interesting in the assignment construct. It looks like
-> and allows you to do multiple assignments:
10->j -> k;
i + 3 * j->k ;
Using the same syntax, you can send data to objects, just like in C ++:
'Hello, World!'->putline;
But the most interesting is the possibility of implementing cycles. For example, a legitimate loop looks like this:
X -> Root;
L: (if (X-Root*Root -> fabs) > X / 10E6 then
0.5 * (Root + X div Root) -> Root;
restart L;
if);
And all this despite the fact that there is nothing fundamentally new in front of us - the same cycles, the assignment operator, the if operator. Just removed some restrictions and added new ones.
Eiffel
This
beautiful programming language was remembered by the fact that it has only one cycle operator, but it is very functional and minimalistic. Here is his definition (from Wikipedia):
from
until
loop
end
None of these parts, except the loop ... end, is optional. Thus, we ourselves make the cycle as we want. Need an endless loop? We leave only the loop ... end. Need a while loop? until ... loop ... end.
I do not know from what, but I like such “designers”. After all, we use the optional else-branch in conditional operators, and why not use this method to define loops?
Icon
Icon is positioned as a very high-level language. After reviewing the following examples with my comments, it is difficult to disagree with this statement. Path Icon - work with strings, he really copes with this. What's so interesting? Yes, almost everything, I do not even know where to start.
In Icon with strings, you can perform logical operations and you can write something like
S:="ab"
S:=S || "cd" # S == "abcd"
For me, this is more logical than the use of the operator + in languages such as Pascal or BASIC. After all, even the name of the operation - concatenation, speaks for itself. Moreover, there is another useful construct: the unary operator *. If there is a string after it, then it returns the number of characters in the string:
S:="abcd"
write(*S) # '4'
This is much more elegant than the len () function in other languages (the name may vary, but that is not important). Why is this approach not used in other programming languages? The answer is obvious: ambiguity of characters. Languages such as C ++ or Java are already overwhelmed, and here is another package of problems: do you need to recognize what exactly a character does in a certain place: multiplication, or returning strings are long? Or maybe something terrible is meant:
S:="abcd"
S[3:3]:="aaa"
S[*S+1:*S+1]:="y"
write(S) # , !
I feel that I have to immediately move on to something more traditional ...
')
Factor
Before that, I mostly wrote about unusual variations of syntactic constructions in a neutral way, the reader can decide for himself whether a good idea was put into the language or not. But now I will write about how not to distort the syntax. A prime example: the conditional if statement in the language Factor. The main specificity of the Factor, as well as the Fort, is the inverse notation associated with the stack. Because of this, the condition is evaluated
before the if statement is called. If you write the operator traditionally, it will be something like
IF THEN 1
ELSE 2
END IF
In my opinion, this is disgusting. The developers of the Fort found another solution, it is much better. Now IF shares a condition and then-branch. So,
IF
1
ELSE 2
END IF
But in Factor decided to go the other way. I give only an example of calculating factorial:
: tail-factorial
dup 0 =
[ drop ]
[ [ * ] [ 1 - ] bi tail-factorial ]
if ;
Question: did you understand something? I understood only one thing on the move - there are no then and else, and if he himself was hidden after both branches! Meaning? You are reading the code, reading, reading ... and at the very end you suddenly realize that these are branches of the conditional operator. In Forte, it is immediately clear what is in front of you - a cycle, or a condition. Also, in Forte, the logical structure of the program is better visible, while in Factore, it is only a set of square brackets. Wise-wise, they have become too smart ...
Ada
In this powerful but complex programming language, I remember the assignment of arrays as a whole and the improved begin ... end brackets. With them we begin. At the time when I taught Pascal, I was terribly annoyed that I could not declare variables where I wanted. In Ada, this issue is resolved. Before begin ... end, I can insert a declarative part, where I define all the variables and data that are used only in this block. Example:
declare
i : integer;
begin
-- , i
end;
-- i !
The second interesting point is the assignment of arrays entirely. Suppose we have two identical arrays, a and b. We need to copy all the data from a to b. In Ada, this process can be done in one action by writing b: = a. But there is one thing: how does the compiler know that arrays are the same? For this we can create a base type, we call it Test_Array:
type Test_Array is array (1..50) of Integer;
Now we declare a and b as instances of this type:
a, b : Test_Array;
The compiler remembers that arrays are identical in terms of type and now allows operations like a: = b. In Ada in general, the flavor of OOP concepts is very much felt.
Another very curious thing: units. But in many languages, the aggregates do not even have an approximate analogue, and the very description of the aggregates is not very simple. Therefore, I refer the curious to the relevant
article .
Push
I would venture to offer my own ideas to the public. First of all, why not make the if statement accept more than one condition, but a list of conditions, separated by a comma?
if 1, 2, ... , N then
...
end if
If at least one condition turns out to be false, then the else-branch is executed, if it exists. Why do you need it? Suppose we have several conditions that must be true for the then-branch to be fulfilled. Then we will write something like
if (1) and (2) and (3) then ...
Now suppose that each condition is rather complicated, and the individual logical operators with their operands have to be framed in brackets so that the translator can understand them correctly. As a result, we get mountains of brackets and nothing else. Of course, such situations are very rare, and arise about in one case out of a thousand, but when they arise ... My proposal allows you to reduce the load on the brackets, this will allow you to better understand your own program in a month. In general, the list of conditions after if will reduce the likelihood of writing such horrors:
if (figureX > leftLimit && figureX < fightLimit && figureColor == GREEN)
Even if the conditions are separated in different lines, the semicolon looks more elegant (although ... this is a matter of taste):
if (figureX > leftLimit,
figureX < fightLimit,
figureColor == GREEN) ...
I do not think that the community will take this idea positively, I myself do not insist on it. But it happens with all new things and concepts. The idea is well suited for languages like Pascal, where sometimes an unhappy programmer literally sinks in brackets when describing conditions.