This commit is contained in:
Miloslav Ciz 2023-03-21 21:26:47 +01:00
parent 3b27159e33
commit f48a2a80fa
6 changed files with 38 additions and 22 deletions

View file

@ -1,22 +1,22 @@
# Algorithm
Algorithm is an exact description of how to solve a problem. Algorithms are basically what [programming](programming.md) is all about: we tell computers, in very exact ways (with [programming languages](programming_language.md)), how to solve problems -- we write algorithms. But algorithms don't have to be just computer programs, they are simply instruction for solving problems.
Algorithm (from the name of Persian mathematician Muhammad ibn Musa al-Khwarizmi) is an exact step-by-step description of how to solve some type of a problem. Algorithms are basically what [programming](programming.md) is all about: we tell [computers](computer.md), in very exact ways (with [programming languages](programming_language.md)), how to solve problems -- we write algorithms. But algorithms don't have to be just computer programs, they are simply instruction for solving problems.
Cooking recipes are sometimes given as an example of a non-computer algorithm (though they rarely contain branching and loops, very typical features of algorithms). The so called wall-follower is a simple algorithm to get out of any maze: you just pick either a left-hand or right-hand wall and then keep following it. You may write a crazy algorithm for how to survive in a jungle, but it has to be **exact**; if there is any ambiguity, it is not considered an algorithm.
Cooking recipes are commonly given as an example of a non-computer algorithm, though they rarely contain branching and loops, the key features of an algorithm. The so called wall-follower is a simple algorithm to get out of any maze: you just pick either a left-hand or right-hand wall and then keep following it. You may write a crazy algorithm basically for any kind of problem, e.g. for how to clean a room or how to pick up a girl, but it has to be **precise** so that anyone can execute the algorithm just by blindly following the steps; if there is any ambiguity, it is not considered an algorithm.
Interesting fact: contrary to intuition there are problems that are mathematically proven to be unsolvable by any algorithm, see [undecidability](undecidability.md), but for most practically encountered problems we can write an algorithm (though for some problems even our best algorithms can be unusably [slow](time_complexity.md)).
Algorithms are mostly (possibly [not always](declarative.md), depending on definitions) written as a **series of steps** (or instructions); these steps may be specific actions (such as adding two numbers or drawing a pixel to the screen) or **conditional jumps** to other steps ("if condition X holds then jump to step N, otherwise continue"). These jumps can be used to create **[branches](branch.md)** (in programming known as *if-then-else*) and **[loops](loop.md)**. Branches and loops are together known as [control structures](control_structure.md) -- they don't express a direct action but control where we move in the algorithm itself. All in all, **any algorithm can be written with only these three constructs**:
Algorithms are mostly (possibly [not always](declarative.md), depending on exact definition of the term) written as a **series of steps** (or instructions); these steps may be specific actions (such as adding two numbers or drawing a pixel to the screen) or **conditional jumps** to other steps ("if condition X holds then jump to step N, otherwise continue"). At the lowest level ([machine code](machine_code.md), [assembly](assembly.md)) computers can do just that: execute instructions (expressed as [1s and 0s](binary.md)) and perform conditional jumps. These jumps can be used to create **[branches](branch.md)** (in programming known as *if-then-else*) and **[loops](loop.md)**. Branches and loops are together known as [control structures](control_structure.md) -- they don't express a direct action but control which steps in the algorithm will follow. All in all, **any algorithm can be written with only these three constructs**:
- **sequence**: A series of steps, one after another.
- **sequence**: A series of steps, one after another. E.g. "write prompt, read number from input, store than number to memory".
- **selection** (branches, *if-then-else*): Two branches (sequences of steps) preceded by a condition; the first branch is executed only if the condition holds, the second ("else") branch is executed only if the condition doesn't hold (e.g. "If user password is correct, log the user in, otherwise print out an error.").
- **iteration** (loops, repetition): Sequence of steps that's repeated as long as certain condition holds (e.g. "As long as end of file is not reached, read and print out next character from the file.").
Note: in a wider sense algorithms may be expressed in other ways than sequences of steps (non-[imperative](imperative.md) ways, see [declarative languages](declarative.md)), even mathematical equations are often called algorithms because they *imply* the steps towards solving a problem. But we'll stick to the common meaning of algorithm given above.
Additional constructs can be introduced to make programming more comfortable, e.g. [subroutines/functions](function.md) (kind of small subprograms that the main program uses for solving the problem) or [switch](switch.md) statements (selection but with more than two branches). Loops are also commonly divided into several types: counted loops, loops with condition and the beginning and loops with condition at the end (`for`, `while` and `do while` in [C](c.md), respectively). Similarly to mathematical equations, algorithms make use of [variables](variable.md), i.e. values which can change that have a specific name (such as *x* or *myVariable*).
Additional constructs can be introduced to make programming more comfortable, e.g. [subroutines/functions](function.md) (kind of small subprograms that the main program uses for solving the problem), [macros](macro.md) (shorthand commands that represent multiple commands) or [switch](switch.md) statements (selection but with more than two branches). Loops are also commonly divided into several types such as: counted loops, loops with condition and the beginning, loops with condition at the end and infinite loops (`for`, `while`, `do while` and `while (1)` in [C](c.md), respectively) -- in theory there can only be one generic type of loop but for convenience programming languages normally offer different "templates" for commonly used loops. Similarly to mathematical equations, algorithms make use of [variables](variable.md), i.e. values which can change and which have a specific name (such as *x* or *myVariable*).
Practical programming is based on expressing algorithm via [text](text.md), but visual programming is also possible: [flowcharts](flowchart.md) are a way of visually expressing algorithms, you have probably seen some. [Decision trees](decision_tree.md) are special cases of algorithms that have no loops, you have probably seen some too. Even though some languages (mostly educational such as [Snap](snap.md)) are visual and similar to flow charts, it is not practical to create big algorithms in this way -- serious programs are written as a text in [programming languages](programming_language.md).
Practical programming is based on expressing algorithms via [text](text.md), but visual programming is also possible: [flowcharts](flowchart.md) are a way of visually expressing algorithms, you have probably seen some. [Decision trees](decision_tree.md) are special cases of algorithms that have no loops, you have probably seen some too. Even though some languages (mostly educational such as [Snap](snap.md)) are visual and similar to flow charts, it is not practical to create big algorithms in this way -- serious programs are written as a text in [programming languages](programming_language.md).
## Example
@ -45,15 +45,15 @@ Notice that *x*, *divisor counter* and *currently checked number* are [variables
V
set checked number to 1
|
------------>|
.----------->|
| |
| V no
| checked number <= x ? -------
| checked number <= x ? ------.
| | |
| | yes |
| V |
| checked number no |
| divides x ? -------- |
| divides x ? -------. |
| | | |
| | yes | |
| V | |
@ -61,21 +61,21 @@ Notice that *x*, *divisor counter* and *currently checked number* are [variables
| count by 1 | |
| | | |
| | | |
| |<------------- |
| |<------------' |
| | |
| V |
| increase checked V
| number by 1 print divisor count
| | |
-------------- |
'------------' |
V no
divisor count = 2 ? ------
divisor count = 2 ? -----.
| |
| yes |
V |
print "number is prime" |
| |
|<----------------
|<---------------'
V
END
@ -124,9 +124,9 @@ int main(void)
## Study of Algorithms
As algorithms are at the heart of [computer science](scompsci.md), there's a lot of rich theory and knowledge about them.
Algorithms are the essence of [computer science](scompsci.md), there's a lot of theory and knowledge about them.
[Turing machine](turing_machine.md), a kind of mathematical bare-minimum computer, created by [Alan Turing](turing.md), is the traditional formal tool for studying algorithms, though many other [models of computation](model_of_computation.md) exist. From theoretical computer science we know not all problems are [computable](computability.md), i.e. there are problems unsolvable by any algorithm (e.g. the [halting problem](halting_problem.md)). [Computational complexity](computational_complexity.md) is a theoretical study of resource consumption by algorithms, i.e. how fast and memory efficient algorithms are (see e.g. [P vs NP](p_vs_np.md)). [Mathematical programming](mathematical_programming.md) is concerned, besides others, with optimizing algorithms so that their time and/or space complexity is as low as possible which gives rise to algorithm design methods such as [dynamic programming](dynamic_programming.md) ([optimization](optimization.md) is a less theoretical approach to making more efficient algorithms). [Formal verification](formal_verification.md) is a field that tries to mathematically (and sometimes automatically) prove correctness of algorithms (this is needed for critical software, e.g. in planes or medicine). [Genetic programming](generic_programming.md) and some other methods of [artificial intelligence](ai.md) try to automatically create algorithms (*algorithms that create algorithms*). [Quantum computing](quantum.md) is concerned with creating new kind of algorithms algorithms for quantum computers (a new type of still-in-research computers). [Programming language](programming_language.md) design is an art of finding best ways of expressing algorithms.
[Turing machine](turing_machine.md), a kind of mathematical bare-minimum computer, created by [Alan Turing](turing.md), is the traditional formal tool for studying algorithms, though many other [models of computation](model_of_computation.md) exist. From theoretical computer science we know not all problems are [computable](computability.md), i.e. there are problems unsolvable by any algorithm (e.g. the [halting problem](halting_problem.md)). [Computational complexity](computational_complexity.md) is a theoretical study of resource consumption by algorithms, i.e. how fast and memory efficient algorithms are (see e.g. [P vs NP](p_vs_np.md)). [Mathematical programming](mathematical_programming.md) is concerned, besides others, with optimizing algorithms so that their time and/or space complexity is as low as possible which gives rise to algorithm design methods such as [dynamic programming](dynamic_programming.md) (practical [optimization](optimization.md) is a more pragmatic approach to making algorithms more efficient). [Formal verification](formal_verification.md) is a field that tries to mathematically (and sometimes automatically) prove correctness of algorithms (this is needed for critical software, e.g. in planes or medicine). [Genetic programming](generic_programming.md) and some other methods of [artificial intelligence](ai.md) try to automatically create algorithms (*algorithms that create algorithms*). [Quantum computing](quantum.md) is concerned with creating new kinds of algorithms for quantum computers (a new type of still-in-research computers). [Programming language](programming_language.md) design is the art and science of creating languages that express computer algorithms well.
## Specific Algorithms
@ -163,7 +163,7 @@ Following are some common algorithms classified into groups.
- [linear search](linear_search.md)
- [other](other.md)
- [A*](a_start.md): path searching algorithm, used by [AI](ai.md) in many [games](game.md)
- [backpropagation](backpropagation.md)
- [backpropagation](backpropagation.md): training of [neural networks](neural_net.md)
- [fizzbuzz](fizzbuzz.md): problem/simple algorithm given in job interviews to filter out complete [noobs](noob.md)
- [FFT](fft.md): quickly converts signal (audio, image, ...) to its representation in frequencies, one of the most famous and important algorithms
- [Huffman coding](huffman_code.md): [compression](compression.md) algorithm

View file

@ -8,7 +8,7 @@ Unless specified otherwise, this article supposes the C99 standard of the C lang
Undefined (completely unpredictable), unspecified (safe but potentially differing) and implementation-defined (consistent within implementation but potentially differing between them) behavior poses a kind of unpredictability and sometimes non-intuitive, tricky behavior of certain operations that may differ between compilers, platforms or runs because they are not exactly described by the language specification; this is mostly done on purpose so as to allow some implementation freedom which allows implementing the language in a way that is most efficient on given platform. One has to be very careful about not letting such behavior break the program on platforms different from the one the program is developed on. Note that tools such as [cppcheck](cppcheck.md) can help find undefined behavior in code. Description of some such behavior follows.
**Data type sizes including int and char may not be the same on each platform**. Even though we almost take it for granted that char is 8 bits wide, in theory it can be wider (even though `sizeof(char)` is always 1). The int (and unsigned int) type width should reflect the architectures native integer type, so nowadays it's mostly 32 or 64 bits. To deal with this we can use the standard library `limits.h` and `stdint.h` headers.
**Data type sizes including int and char may not be the same on each platform**. Even though we almost take it for granted that char is 8 bits wide, in theory it can be different (even though `sizeof(char)` is always 1). Int (and unsigned int) type width should reflect the architecture's native integer type, so nowadays it's mostly 32 or 64 bits. To deal with these differences we can use the standard library `limits.h` and `stdint.h` headers.
**No specific [endianness](endian.md) or even encoding of numbers is specified**. Nowadays little endian and [two's complement](twos_complement.md) is what you'll encounter on most platforms, but e.g. [PowerPC](ppc.md) uses big endian ordering.

View file

@ -2,7 +2,7 @@
*Capitalism is how you enslave people with their approval.*
Capitali$m is the worst socioeconomic system we've yet seen in [history](history.md),^[source](logic.md) based on pure greed, culture of slavery and artificially sustained conflict between everyone in society (so called [competition](competition.md)), abandoning all morals and putting money and profit (so called [capital](capital.md)) above everything else including preservation of life itself, capitalism fuels the worst in people and forces them to compete and suffer for basic resources, even in a world where abundance of resources is already possible to achieve. Capitalism goes against progress (see e.g. [antivirus paradox](antivirus_paradox.md)), [good technology](lrs.md) and freedom, it supports immense waste of resources, wars, abuse of people and animals, destruction of environment, decline of morals, deterioration of art, invention of [bullshit](bullshit.md) (bullshit jobs, bullshit laws, ...), utilizing and perfecting methods of [torture](marketing.md), brainwashing, censorship and so on. In a sense capitalism can be seen as **slavery 2.0**, a more sophisticated form of slavery, one which denies the label by calling itself the polar opposite ("freedom") and manipulates people into them approving and voluntarily parttaking in their own enslavement. However wage and consumption slavery is only a small part of capitalist dystopia -- capitalism brings on destruction basically to every part of civilization. It it also often likened to a [cancer](cancer.md) of society; one that is ever expanding, destroying everything with commercialism, materialism, waste and destruction, growing uncontrollably with the sole goal of just never stop an ever accelerating growth. Nevertheless, it's been truthfully stated that "it is now easier to imagine the end of all life than any substantial change in capitalism." Another famous quote is that "capitalism is the belief that the worst of men driven by the nastiest motives will somehow work for the benefit of everyone", which is describes its principle quite well.
Capitali$m is the worst socioeconomic system we've yet seen in [history](history.md),^[source](logic.md) based on pure greed, culture of slavery and artificially sustained conflict between everyone in society (so called [competition](competition.md)), abandoning all morals and putting money and profit (so called [capital](capital.md)) above everything else including preservation of life itself, capitalism fuels the worst in people and forces them to compete and suffer for basic resources, even in a world where abundance of resources is already possible to achieve. Capitalism goes against progress (see e.g. [antivirus paradox](antivirus_paradox.md)), [good technology](lrs.md) and freedom, it supports immense waste of resources, wars, abuse of people and animals, destruction of environment, decline of morals, deterioration of art, invention of [bullshit](bullshit.md) (bullshit jobs, bullshit laws, ...), utilizing and perfecting methods of [torture](marketing.md), brainwashing, censorship and so on. In a sense capitalism can be seen as **slavery 2.0** or *universal slavery*, a more sophisticated form of slavery, one which denies the label by calling itself the polar opposite ("freedom") and manipulates people into them approving and voluntarily parttaking in their own enslavement. However wage and consumption slavery is only a small part of capitalist dystopia -- capitalism brings on destruction basically to every part of civilization. It it also often likened to a [cancer](cancer.md) of society; one that is ever expanding, destroying everything with commercialism, materialism, waste and destruction, growing uncontrollably with the sole goal of just never stop an ever accelerating growth. Nevertheless, it's been truthfully stated that "it is now easier to imagine the end of all life than any substantial change in capitalism." Another famous quote is that "capitalism is the belief that the worst of men driven by the nastiest motives will somehow work for the benefit of everyone", which is describes its principle quite well.
{ Some web bashing capitalism I just found: http://digdeeper.club/articles/capitalismcancer.xhtml, read only briefly, seems to contain some nice gems capturing the rape of people. ~drummyfish }

View file

@ -4,6 +4,8 @@
Deterministic system (such as a computer program or an equation) is one which over time evolves without any involvement of [randomness](randomness.md) and probability; i.e. its current state along with the rules according to which it behaves unambiguously and precisely determine its following states. This means that a deterministic [algorithm](algorithm.md) will always give the same result if run multiple times with the same input values. Determinism is an extremely important concept in [computer science](compsci.md) and [programming](programming.md) (and in many other fields of science and philosophy).
Determinism is also a **philosophical theory** and aspect of physics theories -- here it signifies that our Universe is deterministic, i.e. that everything is already predetermined by the state of the universe and the laws of physics, i.e. that we don't have "[free will](free_will.md)" (whatever it means) because our brains are just machines following laws of physics like any other matter etc. Many normies believe [quantum physics](quantum.md) disproves determinism which is however not the case, there may e.g. exist hidden variables that still make quantum physics deterministic -- some believe the Bell test disproved hidden variables but again this is NOT the case as it relies on statistical independence of the experimenters, determinism is already possible if we consider the choices of experimenters are also predetermined (this is called [superdeterminism](superdeterminism.md)). [Einstein](einstein.md) and many others still believed determinism was the way the Universe works even after quantum physics emerged. { This also seems correct to me. Sabine Hossenfelder is another popular physicist promoting determinism. ~drummyfish } Anyway, this is already beyond the scope of technological determinism.
[Computers](computer.md) are mostly deterministic by nature and design, they operate by strict rules and engineers normally try to eliminate any random behavior as that is mostly undesirable (with certain exceptions mentioned below) -- randomness leads to hard to detect and hard to fix [bugs](bug.md), unpredictability etc. Determinism has furthermore many advantages, for example if we want to record a behavior of a deterministic system, it is enough if we record only the inputs to the system without the need to record its state which saves a great amount of space -- if we later want to replay the system's behavior we simply rerun the system with the recorded inputs and its behavior will be the same as before (this is exploited e.g. in recording gameplay demos in video [games](game.md) such as [Doom](doom.md)).
Determinism can however also pose a problem, notable e.g. in cryptography where we DO want true randomness e.g. when generating [seeds](seed.md). Determinism in this case implies an attacker knowing the conditions under which we generated the seed can exactly replicate the process and arrive at the seed value that's supposed to be random and secret. For this reason some [CPUs](cpu.md) come with special hardware for generating truly random numbers.
@ -18,8 +20,6 @@ Even if we're creating a program that somehow works with probability, we usually
In theoretical computer science non-determinism means that a model of computation, such as a [Turing machine](turing_machine.md), may at certain points decide to make one of several possible actions which is somehow most convenient, e.g. which will lead to finding a solution in shortest time. Or in other words it means that the model makes many computations, each in different path, and at the end we conveniently pick the "best" one, e.g. the fastest one. Then we may talk e.g. about how the computational strength or speed of computation differ between a deterministic and non-deterministic Turing machine etc.
Determinism is also a philosophical theory that says our Universe is deterministic, i.e. that everything is already predetermined by the state of the universe and the laws of physics, i.e. that we don't have "free will" (whatever it means) etc. Many believe [quantum physics](quantum.md) disproves determinism which is however not the case, there may e.g. exist hidden variables that still make quantum physics deterministic. Anyway, this is already beyond the scope of technological determinism.
**Determinism does NOT guarantee [reversibility](reversibility.md)**, i.e. if we know a state of a deterministic system, it may not always be possible to say from which state it evolved. This reversibility is only possible if the rules of the system are such that no state can evolve from two or more different states. If this holds then it is always possible to time-reverse the system and step it backwards to its initial state. This may be useful for things such as [undos](undo.md) in programs. Also note that even if a system is reversible, it may be computationally very time consuming and sometimes practically impossible to reverse the system (imagine e.g. reversing a cryptographic [hash](hash.md) -- mathematical reversibility of such hash may be arbitrarily ensured by e.g. pairing each hash with the lowest value that produces it).
**Is [floating point](float.md) deterministic?** In theory even floating point arithmetic can of course be completely deterministic but there is the question of whether this holds about concrete specifications and implementations of floating point (e.g. in different programming languages) -- here in theory non-determinism may arise e.g. by some unspecified behavior such as rounding rules. In practice you can't rely on float being deterministic. The common float standard, IEEE 754, is basically deterministic, including rounding etc. (except for possible payload of [NaNs](nan.md), which shouldn't matter in most cases), but this e.g. doesn't hold for floating point types in [C](c.md)!

View file

@ -33,9 +33,11 @@ These are mainly for [C](c.md), but may be usable in other languages as well.
- For the sake of simple computers such as [embedded](embedded.md) platforms **avoid [floating point](floating_point.md)** as that is often painfully slowly emulated in software. Use [fixed point](fixed_point.md), or at least offer it as a [fallback](fallback.md). This also applies to other hardware requirements such as [GPU](gpu.md) or sound cards: while such hardware accelerates your program on computers that have the hardware, making use of it may lead to your program being slower on computers that lack it.
- **[Early branching](early_branching.md) can create a speed up** (instead of branching inside the loop create two versions of the loop and branch in front of them). This is a kind of space-time tradeoff.
- **Division can be replaced by multiplication by [reciprocal](reciprocal.md)**, i.e. *x / y = x * 1/y*. The point is that multiplication is usually faster than division. This may not help us when performing a single division by variable value (as we still have to divide 1 by *y*) but it does help when we need to divide many numbers by the same variable number OR when we know the divisor at compile time; we save time by precomputing the reciprocal before a loop or at compile time. Of course this can also easily be done with [fixed point](fixed_point.md) and integers!
- **Consider the difference between logical and bitwise operators!** For example [AND](and.md) and [OR](or.md) boolean functions in C have two variants, one bitwise (`&` and `|`) and one logical (`&&` and `||`) -- they behave a bit differently but sometimes you may have a choice which one to use, then consider this: bitwise operators usually translate to only a single fast (and small) instruction while the logical ones usually translate to a branch (i.e. multiple instructions with potentially slow jumps), however logical operators may be faster because they are evaluated as [short circuit](short_circuit_eval.md) (e.g. if first operand of OR is true, second operand is not evaluated at all) while bitwise operators will evaluate all operands.
- **Reuse variables to save space**. A warning about this one: readability may suffer, mainstreamers will tell you you're going against "good practice", and some compilers may do this automatically anyway. Be sure to at least make this clear in your comments. Anyway, on a lower level and/or with dumber compilers you can just reuse variables that you used for something else rather than creating a new variable that takes additional RAM; of course a prerequisite for "merging" variables is that the variables aren't used at the same time.
- **To save memory use [compression](compression.md) techniques.** Compression doesn't always have to mean you use a typical compression algorithm such as [jpeg](jpg.md) or [LZ77](lz77.md), you may simply just throw in a few compression techniques such as [run length](run_length.md) or word dictionaries into your data structures. E.g. in [Anarch](anarch.md) maps are kept small by consisting of a small dictionary of tile definitions and map cells referring to this dictionary (which makes the cells much smaller than if each one held a complete tile definition).
- **What's fast on one platform may be slow on another**. This depends on the instruction set as well as on compiler, operating system, available hardware, [driver](driver.md) implementation and other details. In the end you always need to test on the specific platform to be sure about how fast it will run. A good approach is to optimize for the weakest platform you want to support -- if it runs fasts on a weak platform, a "better" platform will most likely still run it fast.
- **Prefer preincrement over postincrement** (typically e.g. in a for loop), i.e. rather do `++i` than `i++` as the latter is a bit more complex and normally generates more instructions.
- **Mental calculation tricks**, e.g. multiplying by one less or more than a power of two is equal to multiplying by power of two and subtracting/adding once, for example *x * 7 = x * 8 - x*; the latter may be faster as a multiplication by power of two (bit shift) and addition/subtraction may be faster than single multiplication, especially on some primitive platform without hardware multiplication. However this needs to be tested on the specific platform. Smart compilers perform these optimizations automatically, but not every compiler is high level and smart.
- **Else should be the less likely branch**, try to make if conditions so that the if branch is the one with higher probability of being executed -- this can help branch prediction.
- Similarly **order if-sequences and switch cases from most probable**: If you have a sequences of ifs such as `if (x) ... else if (y) ... else if (z) ...`, make it so that the most likely condition to hold gets checked first, then second most likely etc. Compiler most likely can't know the probabilities of the conditions so it can't automatically help with this. Do the same with the `switch` statement -- even though switch typically gets compiled to a table of jump addresses, in which case order of the cases doesn't matter, it may also get compiled in a way similar to the if sequence (e.g. as part of size optimization if the cases are sparse) and then it may matter again.

View file

@ -2,8 +2,22 @@
*Not to be confused with [coding](coding.md).*
Programming is the act and [art](art.md) of writing computer [programs](program.md); it involves creation of [algorithms](algorithm.md) and [data structures](data_structure.md) and implementing them in [programming languages](programming_language.md).
Programming is the act, [science](science.md) and [art](art.md) of writing computer [programs](program.md); it involves creation of [algorithms](algorithm.md) and [data structures](data_structure.md) and implementing them in [programming languages](programming_language.md).
You may also encounter the term [coding](coding.md) which is used by [noob](noob.md) [wannabe programmers](soydev.md), so called "coders" or [code monkeys](code_monkey.md). "Coding" doesn't reach the quality of programming, it is done in baby handholding languages like [Python](python.md), [JavaScript](javascript.md) or [Rust](rust.md) by people with very shallow knowledge of technology and its context, barely qualified to turn on a computer (like [jewtubers](youtube.md)), who have flooded the computer industry since it became lucrative. What they do is not real programming. Do not try to imitate them.
At high level programming becomes [spiritual](spirituality.md). Check out e.g. the famous [Tao of Programming](tao.md) (yes, it's kind of a [joke](jokes.md) but it's based on reality, programming can truly be kind of a [meditation](meditation.md) and pursuit of enlightenment). Many people say that learning programming opens your eyes in a certain new way, you then see the world like never before (but that's probably kind of true of almost all skills so this may be a [shit](shit.md) statement). Others say too much programming cripples you mentally and gives you [autism](autism.md). Anyway it's [fun](fun.md). Programming requires a good knowledge of advanced [math](math.md). Also probably at least above average [IQ](iq.md), as well as below average social intelligence. Being a [man](man.md) is an advantage.
At high level programming becomes [spiritual](spirituality.md). Check out e.g. the famous [Tao of Programming](tao.md) (yes, it's kind of a [joke](jokes.md) but it's based on reality, programming can truly be kind of a [meditation](meditation.md) and pursuit of enlightenment). Many people say that learning programming opens your eyes in a certain new way, you then see the world like never before (but that's probably kind of true of almost all skills so this may be a [shit](shit.md) statement). Others say too much programming cripples you mentally and gives you [autism](autism.md). Anyway it's [fun](fun.md). Programming requires a good knowledge of advanced [math](math.md). Also probably at least above average [IQ](iq.md), as well as below average social intelligence. Being a [man](man.md) is an advantage.
## How To Learn Programming And Do It Well
The key thing to becoming a programmer is learning a [programming language](programming_language.md) very well (and learning many of them), however this is not enough (it's only enough for becoming a coding monkey), you additionally have to have a wider knowledge such as general knowledge of computers ([electronics](electronics.md), [hardware](hardware.md), theory or computation, [networks](networking.md), ...), tech [history](history.md) and culture ([free software](free_software.md), [hacker cutlure](hacking.md), [free culture](free_culture.md), ...), [math](math.md) and [science](science.md) in general, possibly even society, philosophy etc. Programming is not an isolated topic (only coding is), a programmer has to see the big picture and have a number of other big brain interests such as [chess](chess.md), voting systems, linguistics, physics, music etc. Remember, becoming a good programmer takes a whole life, sometimes even longer.
**Can you become a good programmer when you're old?** Well, as with everything to become a SERIOUSLY good programmer you should have probably started before the age of 20, the majority of the legend programmers started before 10, it's just like with sports or becoming an excellent musician. But with enough enthusiasm and endurance you can become a pretty good programmer at any age, just like you can learn to play an instrument or run marathon basically at any age, it will just take longer and a lot of energy. You don't even have to aim to become very good, becoming just average is enough to write simple gaymes and have a bit of fun in life :) Just don't try to learn programming because it seems cool, because you want to look like movie haxor, gain followers on youtube or because you need a job -- if you're not having genuine fun just thinking before sleep about how to swap two variables without using a temporary variable, programming is probably not for you.
**Which programming language to start with?** This is the big question. Though languages such as [Python](python.md) or [JavaScript](javascript.md) are objectively really REALLY bad, they are nowadays possibly the easiest way to get into programming, so you may want to just pick one of these two, knowing you'll abandon it later to learn a true language such as [C](c.md) (and knowing the bad language will still serve you in the future in some ways, it's not a wasted time). Can you start with C right away? It's probably not impossible for a genius but it will be VERY hard and you'll most likely end up failing, overwhelmed, frustrated and never returning to programming again. Absolutely do NOT even consider [C#](c_sharp.md) (shit, unusable), [Java](java.md) (shit, slow, bloated, unusable), [C++](cpp.md) (like C but shit and more complicated), [Haskell](haskell.md) (non-traditional, hard), [Rust](rust.md) (shit, bad design, unusable), [Go](go.md) (prolly hard), [Lisp](lisp.md) (non-traditional), [Prolog](prolog.md) (lol) and similar languages -- you may explore these later. Whichever language you pick for the love of god **avoid [OOP](oop.md)** -- no matter what anyone tells you, when you see a tutorial that uses "classes"/"objects" just move on, learn normal [imperative](imperative.md) programming. OOP is a huge pile of shit meme that you will learn anyway later (because everyone writes it nowadays) so that you see why it's shit and why you shouldn't use it.
{ I really started programming in [Pascal](pascal.md) at school, it was actually a good language as it worked very similarly to C and the transition later wasn't that hard, but nowadays learning Pascal doesn't make much sense anymore. ~drummyfish }
**[Games](game.md) are an ideal start project** because they're [fun](fun.md) (having fun makes learning much faster and enjoyable), there are many noob tutorials all over the Internet etc. However keep in mind to **start EXTREMELY simple.** -- this can't be stressed enough, most people are very impatient and eager and start making an RPG game or networking library without really knowing a programming language -- this is a GUARANTEED spectacular failure. At the beginning think in terms of "snake" and "minesweeper". Your very first project shouldn't even use any [GUI](gui.md), it should be purely [command-line](cli.md) text program, so a text-only tiny interactive story in [Python](python.md) is possibly the absolutely best choice as a first project. Once you're more comfortable you may consider to start using graphics, e.g. Python + [Pygame](pygame.md), but still [KEEP IT SIMPLE](kiss.md), make a flappy bird clone or something. As you progress, consider perhaps buying a simple toy computer such as an [open console](open_console.md) -- these toys are closer to old computers that had no operating systems etc., they e.g. let you interact directly with hardware and teach you a LOT about good programming by teaching you how computers actually work under the hood. One day you will have to make the big step and **learn [C](c.md)**, the best and most important language as of yet, but be sure to only start learning it when you're at least intermediate in your start language (see our [C tutorial](c_tutorial.md)). To learn C we recommend our [SAF](saf.md) library which will save you all headaches of complex APIs and your games will be nice and compatible with you small toy computers.
TODO