# Is it possible to make a language that can build upon itself perfectly?

First of all, note that I'll have to explain my thoughts in a layman's terms.

There are so many high-level programming languages out there that compete with each other. This means we have to build the same functionality over and over again in each language.

Therefore, I wonder the following:

Why isn't there one language that has come to dominate because it's the most efficient and the most robust, being built from the bottom up perfectly?

Of course, 'perfectly' isn't well defined, so let me try to explain what I mean by this.

As far as I'm aware, all operations on computers boil down to working with 1's and 0's. This makes me think that there's a better way to do things.

For example, take ASCII. Why is ASCII the way it is? It's arbitrary that M is 01101101. This arbitrariness seems like it's the root of the problem; that if M's representation was determined by how and where M's manifested themselves in our data, that the processing language would be a common language, instead of ASCII.

First of all, am I way off base on this intuition? Secondly, let me provide an idea of what I think could at least partially solve this issue.

Imagine I had a functional language that took bits, transformed them in every way possible, and returned bits. I can only think of what this might look like with the constraint that the bits remain the same length. for example, it's functionality (higher level pseudocode) would look something like this:

proc get_transform_list(bit_list, desired_bit_list):
transform_list = []
current_bit_list = bit_list
for i in len(bit_list)^2:
affected_indices = get_list_of_one_indices_from_number(i) // returns list of 'on' indices in binary representation of i
wrong_indicies = get_list_of_bad_indicies(current_bit_list, desired_bit_list) // returns list of indices in current_bit_list that don't match the desired_bit_list
if {any wrong_indices match any affected_indices}:
transform_list.append(1)
new_bit_list = []
for x, bit in enumerate(current_bit_list):
if x in affected_indices:
new_bit_list.append(not bit)
else:
new_bit_list.append(bit)
current_bit_list = new_bit_list
else:
transform_list.append(0)
return transform_list


So I know that might be annoying to compile in your head so let me give you an example of what this does:

current_bit_list = 1110
desired_bit_list = 0111

we need to get the transform_bit_list for:
1110 -> 0111

| = flip - affected index
. = stay - non-affected index

0 = .... = 1110
1 = ...| = 1111
0 = ..|. = 1111 (corresponding indices are already accurate).
0 = ..|| = 1111 (corresponding indices are already accurate).
0 = .|.. = 1111 (corresponding indices are already accurate).
0 = .|.| = 1111 (corresponding indices are already accurate).
0 = .||. = 1111 (corresponding indices are already accurate).
0 = .||| = 1111 (corresponding indices are already accurate).
1 = |... = 0111
0 = |..| = 0111 (corresponding indices are already accurate).
0 = |.|. = 0111 (corresponding indices are already accurate).
0 = |.|| = 0111 (corresponding indices are already accurate).
0 = ||.. = 0111 (corresponding indices are already accurate).
0 = ||.| = 0111 (corresponding indices are already accurate).
0 = |||. = 0111 (corresponding indices are already accurate).
0 = |||| = 0111 (corresponding indices are already accurate).
||
|| > 0100000010000000
(flipping them all first which would be a reverse path is 0111011001111101)

the transition_bit_list is 0100000010000000


Using this method or something like it you can get from one bit representation to any other bit representation and you have an inherent list of representations between them (this inherent list comes from the structure of binary, but it could be something else).

I know the value and use for this kind of thing is so vague and esoteric, so let me get to the point and reiterate my question once again in a different way.

I guess what I'm trying to ask is: ascii is an example of an arbitrary protocol, but if we made all protocols dependant upon protocols below them wouldn't we have no arbitrary protocols, and therefore wouldn't we have just one universal programming language?

• xkcd.com/927
– D.W.
Apr 4 '18 at 22:43
• Possible duplicate of Why are there so many programming languages? Apr 4 '18 at 22:56
• Why do you think that the binary representation of the letter M is a fundamentally important to computation? Explain it to a Chinese person. Apr 6 '18 at 9:53
• The value of M is absolutely not random and arbitrary. Apr 6 '18 at 11:32

Interesting that you reflect on this issue. This is very similar to the issues that I was reflecting on when I started my Phd research back in 1976.

Back then Extensible Languages were very in vogue. The thesis then was that there must be some core of semantic and syntactic elements that could be used as the basis for all other languages. If we constructed the one Master Language it could then be extended to become anything we wanted. All that was needed was some understanding of the atomic units of semantics. All we had to do was start at a language and extend backwards to the atomic indivisible components that could not be further subdivided. This would be the basis of the one universal language which could both express all languages and replace them.

Work on ultimate semantics also led in the of the one machine instruction that could replace all others. The ultimate RISC machine.

As we don't yet have an answer, some are still continuing to reflect.

• cool, so if I wanted to learn more, I should look into "RISC" Machine? I think truly the answer to this will end up being the pure expression of intelligence. But I want to read what everyone has thought on the topic Apr 4 '18 at 23:14

Although you're question states to be about programming language, it seems to me there are also some questions on encoding that still need answering. Let's start with the ASCII.

As you've said, the encoding is arbitrary. It seems you don't like this and would rather have an 'non-arbitrary' encoding. This hard to do, but more importantly, we don't want to do have 'non-arbitrary' encoding.

Standards like ASCII allow us to have abstraction. When typing this text, I don't want to know what the ASCII (or technically, Unicode, I guess) codes are for all characters I type.

The same holds for programming languages, high level programming languages abstract from their compiled assembly code. But even for assembly languages, the encoding to binary is, from the programmer's perspective, arbitrary. However, there may be good reasons for the processor designer to choose a certain encoding. The fact that the programmer doesn't care about the encoding means the processor designer can choose whatever encoding that is convenient.

However, all of the above are practical reasons why the current situation is fine. As Brian Tompsett states, a Master Language is however something that would be interesting in theory, even if it isn't needed in practice.

• Thanks for your answer, I am of course aware of abstraction and the usefulness of the concept, so I think I'm being at least partly misunderstood. Let me explain the question by analogy: why is biology the way it is? because chemistry is the way it is. Why is chemistry chemistry? Because of quantum physics. Structure is built on top of structure and is determined by it. Programming languages are constrained by structure below them but are not wholly determined by it. There are arbitrary decisions made about how concepts are abstracted up and up. But what if there was no arbitrariness? Apr 6 '18 at 14:47

Three thoughts for you, and a bonus.

1. In any problem there are tradeoffs: some solutions are better by some measure but worse by another. For example, C usually runs faster than Python, but takes more lines of code to express the same program. So many language designs decisions are not arbitrary, but they are different in different languages due to tradeoffs.

2. Pragmatically, languages work well if they focus and limit expressivity to the most useful areas for problems that language wants to solve. We could have everyone program in machine code or assembly language, which only depend on the underlying hardware. But we abstract common tasks out and build higher-level languages to do them quickly. Which abstractions should we build? If one language tried to hold them all, it would be too impossibly large to understand. Instead, we pick some set of tasks and focus the language toward those.

3. Progress is hard and we do not know everything. Slowly we learn and improve and design new languages, but we don't always know what will work. There are many goals and factors. Your goal may be a good one but we don't know how to do it yet -- each new programming language is an experiment around a few areas of improvement.

Think about image file formats. Why do we have PNG, GIF, JPG, SVG, and so many more? Because there are tradeoffs in how we store images, and each format works well by focusing on what it is good at, and there is progress over time as we learn how to better compress and display images.

Bonus. You may be interested in LISP or different variants of it. LISP is a language with very minimal and consistent syntax: everything is a list and delimited with parentheses, so data and code are written the same way and can be manipulated in the same ways.