Informatics


The first programmer is said to be Ada Lovelace, an English mathematician and writer (a woman!). In 1842, she wrote a program for a computer called Analytical Engine. However, that program never worked, because the computer it was written for was never finished.

The inventor of modern computer is said to be Konrad Zuse. In 1936, he made a computer called Z1. At the end of the 20th century, his ideas were reconsidered, and his computer was proven to be about as computationally powerful as the modern computers are. He was so advanced that he wasn't understood in his time.


Why am I interested in informatics?

Before we begin, let me make it clear I am not one of those people who are saying programming is an easy way to make money. It is not, I will share my Reddit post about it here:
Don't expect it to be so easy. I have been trying to learn to program for 8 years now and I still have not managed to get an entry-level job. This applies to many things in life: beware of the survivorship bias. Don't listen just to the success stories, listen also to those who did not succeed. If you listen only to the success stories, you will have a very mistaken picture of reality.
I have spent much of my time preparing for programming competitions such as Infokup and the Croatian Open Competition in Informatics. I thought they will make me a competent programmer. Not only did they not make me a competent programmer, they might even have made me worse (as they encourage bad programming practices, such as short variable names, and give people bad instincts that, if a program is slow, it is usually because of the algorithm). I also thought that, once I build a compiler for my programming language targeting WebAssembly, any employer would be impressed. So I spent a lot of my time learning about relevant things and building it. As it turns out, no employer is impressed by such things these days. The barrier to entry to the world of programming is high, and it gets even higher as the time passes (and computers become more complicated, and an average person is more able to build a website so more is expected from a programmer...).
I am sorry if I bursted your bubble, but a little slap of reality into your face will save you from a lot of pain later.
And do not expect universities to help you with programming significantly. Let me tell you an anecdote from my experience studying computer science at the university: During the summer break, my father asked me which courses I have the next semester. I was naming the courses, and, when I said "object-oriented programming", my father interrupted me and said "How? Object-oriented programming? A really weird name. And, is there then some subject-oriented programming?" I said that, as far as I know, there isn't. Then my father said: "I guess that's something that we historians can't understand. No, that, on Croatian language, that's not a good name.". After a few weeks, we met with some old friend of his. And my father told me: "So, tell him, what's the name of the course you have this semester.". So, I repeated: "object-oriented programming". And then my father asked him: "So, what does that name mean? Can you guess? Well, can you think of a name that's more stupid?". And the friend of my father said: "Well, I guess it's called object-oriented because programming is usually done by mathematicians and people from natural sciences. If programming were done by historians or poets, then it would be called subject-oriented programming.". I hope you get some idea how difficult it is to study computer science at the university. And it is important to understand that programming which is done at the university has little to do with programming in real life. Studying computer science at the university will familiarize you with computer science, electrical engineering (If you do not know what is electrical engineering, here is a quote from my professor Željko Hederić that I think wonderfully illustrates that: "When you try to spill water from a glass, the water will not start spilling all until some air gets into the glass, do we agree? Similarly, the electricity will not start flowing from a socket all until some magnetic field does not get into that socket. And that is, basically, what the Biot-Savart Law is saying.") and advanced mathematics (Much of the advanced mathematics is things you already know but in a very confusing language. Here is a joke I have written about it in Latin, based on a true story: Hodie in universitate (ego studeo scientiam computorum) docebamur de theoria unionum. Professor nobis explicabat, cur numerus cardinalis unionis unionum non semper sit summa (additio) cardinalum numerorum unionum: "Si hoc veritas esset, canis debet octo crura habere. Canis enim habet duo crura antica, duo crura posteriora, duo crura laeva, et duo crura dextera. Summa (additio) numerorum cardinalium earum unionum octo (quater bini) est, sed numerus cardinalis unionis earum unionum, sane, quattuor est.".). By the way, professors will often be angry, and with an understandable reason. In real life, programming rarely involves advanced knowledge of even computer science (I think there are only two times in my projects where knowledge of computer science helped me significantly, when I used DFS algorithm to avoid stack overflow in my AEC-to-x86 compiler and when I used LCS algorithm from Dynamic Programming in my AEC-to-WebAssembly compiler to provide corrections for misspelled variable names; It is also possible this little knowledge of computer science that I have has guided me astray multiple times, as somebody on Discord suggested me a better solution for providing corrections for misspelled variable names than using LCS.), yet alone electrical engineering (I think my knowledge of electrical engineering never helped me with my projects) or mathematics (I think the only time my knowledge of advanced mathematics helped me is when implementing mathematical functions into my AEC-to-WebAssembly compiler). When you program in the real world, you will probably spend most of your time with things such as getting your web-app to work in Internet Explorer, or something equivalent to that in parts of programming not related to web-apps (The thing that bothers me with making the compiler for my programming language right now is that, after I added the suggestions for misspelled variable names, the compiler crashes if it is compiled with Visual Studio or CLANG with some options on Windows, but apparently not if it is compiled using any other C++ compiler. What you will spend most of your time dealing with when programming are those annoying little things about programming tools that have little or nothing to do with the problem you are trying to solve. While stuff in programming languages such as portability, compiler warnings and exceptions are good things, you need to understand that, quite often, they are illusory and lulling programmers into false sense of security. A program that compiles and works in one C++ compiler can very well not even compile in another one, yet alone work. And it is also like that with Java. Java is supposed to be a compile-once-run-everywhere language, but a lot better description is compile-once-debug-everywhere. In theory, if you are triggering undefined behaviour, the C++ compilers should give you a warning. In reality, often enough for that to be a problem, none of them will end up warning you, as has happened in my case. In theory, if your program is misusing the C++ standard library, the C++ standard library should throw an exception, and that is what exceptions in programming languages are for. In reality, unless you know how the C++ standard library works in the smallest details, what will sooner or later happen is that your program will appear to work except for sometimes unpredictably having segmentation faults under one compiler, on an operating system under which the debugging tools you know how to use are not working. And there are reasons why C++ compilers and standard library are so permissive. The first reason is that there is a bunch of bad code already present in C++ projects, and compilers which complain about them will be perceived as faulty. I know how annoyed I feel when I try to build from source an older open-source C++ project with a modern C++ compiler and get tons of error messages, while using an older C++ compiler works. There is, unfortunately, an incentive not to fix ages-old bugs in programming languages and programming tools. The second reason is that C++ compilers and standard libraries need to make trade-offs between catching errors and being fast enough for correct programs that need high performance and fast compilation times. These are problems with computers that have nothing to do with computer science, yet alone mathematics or engineering, but which programmers need to deal with every day.). You will gain next-to-no experience with that at the university, as the programming tools used at the university are different from the programming tools used in real life. JavaScript, for example, is taught very little at the university, and it is the most popular programming language these days, and will likely remain so in the future. Not because it is a good language, in fact, it is widely agreed to be an exceptionally poorly designed language, full of quirks which programmers need to spend a lot of time learning to use it effectively. It is the most popular programming language because of the technicallity that, in order to make your application run in an Internet browser, for most of the time the Internet has existed, there was no alternative. WebAssembly will replace a part of JavaScript, but probably not most of it. At the university, you will gain a lot of experience with programming languages such as MatLab, which is almost never used for software development in the real world, and is also very different from the languages used in the real world. My perception is that the knowledge that is gained at the university helps only when dealing with stuff such as nuclear reactors or medical devices. In those cases, it is useful to be able to make academic arguments that your program will work correctly in unexpected situations. In most other cases, though, knowledge that is gained at the university is not useful. If you will like to read more about what I think about the way programming is taught at the university, click here.
OK, now we can continue...
So, why am I interested in informatics? Becuase it works! I see that if I write something in one of the so-called programming languages, a computer understands me. Sometimes it's hard to understand a computer, and it's often hard to make yourself understood by a computer, but that's because computers are different from human beings. They can easily do things human beings have no hope of doing, like displaying animations (which is basically drawing tens of images per second).
So, what are programming languages? Well, see, computers natively understand only machine code, made of ones and zeros. It's very hard for us to understand the language of ones and zeros. For similar reasons, computers have a very hard time understanding the human languages. That's why we needed to invent some special languages both humans and computers could understand. These are called programming languages. There are programs that translate the programming languages to ones and zeros, these are called compilers and interpreters.
So, what are programming languages like? Well, there are two basic types of programming languages. One are the so-called imperative languages, and the others are called declarative languages. An example of an imperative language is C++, and an example of a declarative language is Haskell. Here is an on-line compiler for C++, and here is an on-line interpreter for Haskell. In declarative languages, the sentences would mostly translate to human languages as strict mathematical definitions, and in imperative languages, they would mostly translate as imperatives.
To explain the difference between the programming languages, I will use the following example of a simple program. Leonardo from Pisa, also known as Fibonacci, was a mathematician who introduced the Arabic numerals to Europe. He lived in the 12th and the 13th century. He has worked on many natural sciences. One of the questions he asked himself was how fast woud rabbits procreate if there was enough food for every single of them. So he did some experiments. What he found out was that there was indeed a rule. Namely, the number of rabbits in some generation is equal to the sum of the numbers of the rabbits in the previous two generations. For instance, if there are three rabbits in the current generation, and there had been two rabbits in the previous generation, there will be five rabbits in the next generation. From then on, the sequence of the numbers in which each one is equal to the some of the previous two is called the Fibonacci sequence. The zeroth number in that sequence is defined to be zero, and the first one to be one. So, that sequence goes like this: 0,1,1,2,3,5,8,13,21... We want to make a program to find some number that's far in that sequence (ignoring the obvious fact that that number would be far larger than the actual number of rabbits in nature because, well, once there are many of them, some of them will die before they procreate either because of the predators or the starvation).
So, how will we do it in Haskell? We just need to translate a strict mathematical definition of the Fibonacci's sequence to it. "Fibonacci's sequence is a sequence of integers (whole numbers). The zeroth number in that sequence is zero. The first one is one. For every other number, its Fibonacci's number is equal to the sum of the two right before it." Here we go:
fibonacci :: Integer -> Integer
fibonacci 0 = 0
fibonacci 1 = 1
fibonacci n = fibonacci (n-1) + fibonacci (n-2)
If you study the code (a set of sentences in a programming language), I believe it will become clear that it's a literal translation of the four sentences, every in their own row.
Now, how will we translate that to C++? We can't do it literally. We need to make an algorithm, a sequence of instructions a computer has to follow in order to calculate it. A concept you probably need to understand for that is called variables. Variables are readable and writable places in memory a symbol is assigned to. They can store various pieces of information, in this case, they will store whole numbers. So, in C++, when you say int a; that means "create a variable that stores integers (int means integer) and assign it the symbol 'a'." (the semicolon, in this case, marks the end of a sentence). Now, if you say a=5;, that means "Store the number 5 in the variable 'a'." If, after that, you say a=a+5, that means "Store the number a+5=5+5 (since we previously stored the number 5 into 'a')=10 into 'a'". So, what we will do is to make a program that will have two variables, 'a' and 'b'. In the beginning, 'a' will be zero and 'b' will be one. Now, we will add 'a' to 'b', and we will then assign the difference between 'b' and 'a' to 'a'. And we will repeat it 'n' times, the number of the Fibonacci's number we are trying to find. Then we will say that 'a' is the nth Fibonacci's number. Let's say we want to find the third Fibonacci's number. So, in the zeroth step 'a' is 0 and 'b' is '1'. In the first step, b=a+b=0+1=1, and a=b-a=1-0=1. In the second step, b=a+b=1+1=2, and a=b-a=2-1=1. And in the third step, b=a+b=1+2=3 and a=b-a=3-1=2. There we go, we will say that the solution is a=2. In C++, we say that we "return" 'a' (that phrase makes sense once you look deeper into the language). The usual way of saying you want to repeat something 'n' times in C++ is to say something that would literally translate as "For every integer 'i' from zero that's smaller than 'n', increasing 'i' every time by one, do...". Without further ado, here is the code:
int fibonacci(int n)
{
    int a=0, b=1;
    for (int i=0; i<n; i=i+1)
    {
        b=a+b;
        a=b-a;
    }
    return a;
}
A bit puzzling? Well, see, C++ is actually way easier to understand by a computer than Haskell is. Also, it gives the programmers more control over their programs. In Haskell, they tell the computer what to do, and in C++, they tell it how to do that. So, they can ensure they do it in an efficient way. Today, you still can't trust the compiler to do it for you. Imperative languages are also more commonly used than declarative languages simply because declarative languages feel alien to most programmers. When programming in declarative languages, you cannot do things the way you are used to doing them. Or, more commonly, you can, but it is discouraged (Haskell has a for-loop, but it is discouraged to use it because it is not idiomatic). An unfortunate but undeniable truth is that, if you designed a perfect programming language (much easier to understand both by humans and by computers than modern programming languages are), programmers would refuse to use it because it would feel too alien.
Imperative languages are divided into the so-called higher and lower imperative languages. C++ is a higher imperative language. Lower imperative languages are rarely used today. They are hard to understand by a human, but easier to understand by a computer. An example of a lower imperative language is Assembly. It has, unlike Haskell or C++, many dialects. In fact, in general, each Assembly compiler has its own dialect of Assembly. So, an Assembly program that works on Windows doesn't work on Linux even if you have an Assembly compiler for Linux. A dialect of Assembly I am somewhat familiar with is Flat Assembler. Here is what the program would look like in Flat Assembler:
.global fibonacci
fibonacci:
mov eax,0
mov ebx,1
mov ecx, edi
loop1:
xchg eax,ebx
add eax,ebx
loop loop1
ret
As you've probably guessed, this is not a literal translation from C++. That's because it can't be. I can't really explain this program simply. eax, ebx, ecx and edi are the so-called registers. They are like variables, except that they aren't in the memory of a computer, but in the processor. mov eax,0 would translate to C++ as eax=0;, and add eax,ebx would translate to eax=eax+ebx;. xchg eax,ebx has no equivalent in C++, it means "Let eax and ebx exchange the numbers stored in them". For instance if eax was 0 and ebx was 1 before that sentence, after that sentence eax would be 1 and ebx would be 0. The words such as mov, add and xchg are called mnemonics. loop1: creates a symbol for a place in a program called loop1. loop loop1 means "If the number stored in ecx is bigger than 0, turn the execution of the program back to loop1 (so that the two sentences between the loop1: and loop loop1 repeat themselves, creating a loop)." We say that loop jumps to loop1. .global fibonacci tells the compiler (actually a program beside the compiler called "linker") that fibonacci isn't a place where you can "jump" on, but a name of a subprogram. So, before another part of a program starts this subprogram, it should store the number whose the Fibonacci's number it wants in edi (if it wants the fifth Fibonacci's number, it should store 5 in edi), and this subprogram should return the result in eax. I hope I've given you some basic idea what the lower imperative language are like. (UPDATE: I've written a compiler in JavaScript for my own simple programming language. The core of it, capable of compiling arithmetic expressions, can be run in browser here. It produces assembly code you can study if you are interested. Command-line version of my compiler, runnable in the JavaScript engines Rhino and Duktape, can compile some rather complicated programs, such as the sorting algorithm I've made. You can see the assembly code it produces for that here. And if you think that's complicated, just look at the assembly code a professional compiler generates for equivalent code here. By the way, if you want to try yourself at assembly language programming, I have made, as a part of a school project, a PicoBlaze Assembler and Simulator in JavaScript. It can be run in a modern browser, you don't need to install, or even download, anything. The program here is in x86 assembly, so it won't work in that simulator, but you have an equivalent program as an example there.)
Today, most of the programs are written in higher imperative languages like C++. We've gone an enormously long way from writing the programs in ones and zeros. There are two main streams of attempts to make the programming languages more productive. One is to make declarative languages, and the other is to keep the languages imperative, but to change their grammar to resemble the grammars of human languages more (like the word order usually being subject-verb-object), and that's called object-oriented programming.
The first one appears to be more scientific. It often does the experiments to determine whether a particular feature makes programming languages more productive. But it's hard to tell because this field of informatics, the comparisons of the programming languages, is filled with pseudosciences. Programmers are often quite dogmatic in defending their favorite programming languages.
While I have a lot of theoretical knowledge of programming, I don't have experience with writing long programs. The most complicated thing I've made is probably the PacMan game I've posted on this site. It's written mostly in Javascript, it's around 550 1300 lines long (it used to be 550 lines long, but I have added many new things to it over the years), and I had to solve a lot of algorithmic problems. (UPDATE on 08/05/2021: As of now, the most complicated program I have made is the compiler for my programming language targetting WebAssembly, being written in C++ and having 5'500 lines of code, excluding the testing parts written in JavaScript and the example programs written in my programming language. The most complicated program I have made in HTML5 is my PicoBlaze Simulator, having 3'500 lines of code.) I've come to an idea to make this website when I learned how much Javascript (a programming language used by Internet browsers) has changed since I last studied it. It's made making websites, web applications and games much easier.
Everything on this website, including the animations and the game, is hand-written in HTML5 (a common name for CSS, Javascript and HTML). I haven't used any special web-designing tools nor frameworks. Looking at the source code of this website might help you study the HTML5, especially since I am still relatively a beginner (not knowing the "dirty tricks").
I hope that it will have some educational value. If you like the way I designed this website, you can make one that looks similar to mine by downloading the template I've designed here (I'll warn you that you will probably want to dodge it to work better in Safari on iPhone, I haven't bothered to make all the features available in a browser full of quirks and without the developer tools allowing me to explore them).


UPDATE on 10/02/2018: I've just made a simple arithmetic-expression-to-assembly compiler in JavaScript, runnable in a browser. I hope that playing with it will be useful in understanding how the programming languages work. If you are going to experiment with Assembly, you should probably use some virtualization software to protect the critical software on your computer from the damage poorly-written or malicious Assembly programs can do. You can read about my experience with free virtualization software here. (The back-end of that compiler can't work since this web-site is hosted on GitHub Pages now, and GitHub Pages doesn't support any PHP!)

UPDATE on 27/09/2019: I've just published two YouTube videos explaining why I think Donald Trump was wrong to ban Huawei, and why I think the new European Union Copyright directives won't be a big deal to the freedom of the Internet. You can see the video about the Huawei ban here (in case you have trouble playing it, try this and this), and you can see the video about Article 11 and Article 13 here (in case you have trouble playing that, try this and this).

UPDATE on 03/11/2019: I've made an example of how to implement the QuickSort algorithm (slightly modified to be easier to implement in a very low-level-language, but not much slower than the traditional QuickSort) in the programming language I made, with comments in Croatian. You can see that here.

UPDATE on 20/11/2019: I've just published a YouTube video showing how you can set up a modern computer to be able to program it in your own programming language.

UPDATE on 23/12/2019: I've just written a seminar in Croatian about my implementation of QuickSort in my programming language, you can download it here (it's available in many different formats, so you almost certainly don't need to install any software in order to read it). If you really can't open any of those files, try this one (the formatting is greatly distorted).

UPDATE on 03/05/2020: I've just made a program in C++ that converts musical notes written in a text file into a simple binary format that can be played by some programs (and converted into mainstream formats by programs that come with Linux), to study how sound is represented in a computer. You can see it, along with hearing an example song, here.

UPDATE on 14/05/2020: I've just made a program that will graphically present Huffman encoding (a primitive form of data compression), you can see it here. I haven't bothered to make it work in old browsers. (UPDATE: I've made it work in Internet Explorer 11, it was easier than I expected. Still, it works in fewer browsers than the PacMan game does, because I relied on advanced JavaScript syntax to describe the algorithm, and there is no obvious way to do it in old JavaScript.)

UPDATE on 23/05/2020: I've just made a program that calculates the properties of the distribution of the numbers in the multiplication table. I don't know how this mathematical distribution is called. It won't work in older browsers, and it will be very hard to make it work there.

UPDATE on 08/08/2020: The Arithmetic Expression Compiler language can now be used to target the JavaScript Virtual Machine using WebAssembly (the textual representation of JavaScript bytecode, which Mozilla has been pushing to get standardized). An example of that is the implementation of the permutation algorithm written in the Arithmetic Expression Compiler language and runnable in modern browsers.

UPDATE on 22/08/2020: I've started a Reddit thread about my programming language. (UPDATE on 18/12/2020: As well, I have written an informal specification of that language.)

UPDATE on 20/11/2020: As a part of a school project, I've written an assembler and a simulator for PicoBlaze (a small computer we use in laboratory exercises in our Computer Architecture classes) in JavaScript, which can be run in a modern browser (relatively modern ones, Internet Explorer 11 does not qualify, but some versions of Microsoft Edge which cannot run programs written in my programming language nevertheless can run that simulator and assembler, and so can Firefox 52, the last version of Firefox runnable on Windows XP). You can see it here.

UPDATE on 07/04/2022: I have made a video debunking Tony Heller's claims about the election fraud. However, YouTube refuses to let me upload it there, so I have uploaded it on GitHub Pages. My best guess as to why it cannot be uploaded is that YouTube's Artificial Intelligence thinks I am claiming the election fraud. Nothing could be further from the truth, I am critical of claiming such a thing. But that's how censorship using artificial intelligence works.

A simple 3D animation
in Javascript.
Hover over it to rotate
the tetrahedron.