# Programming

*Not to be [confused](often_confused.md) with [coding](coding.md).*

Programming is the act, [science](science.md) and fine [art](art.md) of writing [computer](computer.md) [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). It may involve related activities such as [testing](testing.md), [debugging](debugging.md), [hacking](hacking.md) and drinking coffee.

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. It is mostly done for money and/or creating an image for oneself. 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. [zen](zen.md) and the famous [Tao of Programming](tao.md) (yes, it's kind of a [joke](jokes.md) but it's rooted in the reality of a common hacker's mindset, programming can truly be kind of a [meditation](meditation.md) and pursuit of enlightenment, often leading one to asking deeper questions about the world). Many people say that learning programming opens your eyes in a certain new way (with some however claiming the contrary that programming will rather close your eyes), you then see the world like never before (but that's probably kind of true of almost all skills taken to a high level 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) and changes you somehow. **Programming requires a good knowledge of advanced [math](math.md)**. Wanting to do programming without math is like wanting to do biology without chemistry. Programming also demands probably at least above average [IQ](iq.md), as well as below average social intelligence. Being a [white](white.md) [man](man.md) is an advantage.

**Can you do programming without math?** Short answer: no. Long answer: no, you can't.

## How To Learn Programming And Do It Well

*See also [programming tips](programming_tips.md) and [exercises](exercises.md).*

Anyone can (and probably should) learn at least the basics of programming -- even if you just aim to maintain a small server or make a website, you will probably have to learn how to write a simple [script](script.md), and it won't be too difficult, you can learn this from a programming cookbook, just like you can learn to prepare a simple meal without having to become a master chef. Here however we will now assume you aspire to become a GOOD programmer, that you feel programming is something you want to dedicate part of your life to and that it's something you feel joy about for its own sake. How to tell if you're meant for this? You should just feel it. Every true programmer will be able to tell you the story of when he became charmed, when he first saw a computer and realized its potential, when someone showed him a programming language and at that moment the revelation struck him when he saw: "my God, this machine does EXACTLY what I tell it to." Ordinary NPCs just go "oh, that's cool", but the chosen ones just become overwhelmed by excitement, the thought of so many possibilities promptly floods the mind. A normal man perhaps thinks it will simplify his taxes, a true programmer instead can't stop thinking about how to "abuse" and exploit (or more correctly *[hack](hacking.md)*) the machine to do what no one thought about before, regardless of practical utility, appreciating just the intellectual value. If this is you, read on.

At first you have to learn two basic rules that have to be constantly on your mind:

1. **You cannot be a good programmer if you're not good at [math](math.md)** -- real programming is pure math.
2. **[Minimalism](minimalism.md) is the most important concept in programming.** If you don't like, support or understand minimalism, don't even think of becoming a programmer.

OK, now 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](coding.md) monkey), you additionally have to have a wider knowledge such as general knowledge of [computers](computer.md) ([electronics](electronics.md), [hardware](hardware.md), theory or [computation](computation.md), [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](philosophy.md) 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](music.md) 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. **Can you become a good programmer if you're black or [woman](woman.md)?** No. :D Ok, maybe you can, but all the above applies, don't do it for politics or money or followers -- if you become a seriously based programmer (from [LRS](lrs.md) point of view) of unlikely minority, we'll be more than happy to put an apology here, in ALL CAPS and bold letters :) Hopefully this will inspire someone...

**Which programming language to start with?** This is the big question, it also depends on how talented and hardcore you are. 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 -- at least the "mainstream" kind of -- so you may want to just pick one of these two if you just want to start more slow and casual, knowing you'll abandon the language later to learn a real deal such as [C](c.md) or [Forth](forth.md) (and knowing the bad language will still serve you in the [future](future.md) in some ways, it's not a wasted time). Can you start with C right away? It's not impossible for a smart guy but it WILL be hard and there is a big chance you'll end up failing, overwhelmed, frustrated and maybe even never returning to programming again, so be careful. In *How To Become A Hacker* [ESR](esr.md) actually recommends to learn C, [Lisp](lisp.md) or [Go](golang.md) as the first language, but that recommendation really comes to aspiring [hackers](hacking.md), i.e. the most talented and ambitious programmers, so think about whether you fit in this category. 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) (not bad but non-traditional, hard), [Rust](rust.md) (shit, bad design, unusable), [Prolog](prolog.md) (lol) and similar languages -- you may explore some of them later tho (the weird ones, not the bad ones). 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. Also don't let them sell you any kind of new shiny [paradigm](paradigm.md) that's currently trending on [TikTok](tiktok.md) -- learn IMPERATIVE PROGRAMMING and cover your ears when someone talks about anything else. So to sum up, here are some comments on individual languages you might consider:

- [C](c.md): Hardcore choice, only for the real smarts. It's a very good language and you will have to learn it one day anyway, but for absolute beginners may be too much to handle.
- [Python](python.md): Objectively ugly but extremely beginner friendly, simple to use, quite simple to learn, will teach you all the basic concepts. Relaxed choice but you have to keep in mind you'll switch one day.
- [JavaScript](javascript.md): Alternative to Python, similarly friendly to noobs, maybe a tiny bit harder to use, but will allow you to make fun visuals (in web browser) very easily and has a syntax closer to C (so in this learning JavaScript can make you better ready for learning C).
- [Pascal](pascal.md): Language that's kind of dead (though not completely) but which is actually quite nice in that it's very close to C while having been designed as an educational language. Still a more difficult language (has pointers, manual [memory management](memory_management.md), static typing, ...). Consider it an alternative to C if Python/JavaScript still look way too shitty to you.
- [Lisp](lisp.md): Language that's pretty elegant but dissimilar to other ones here and a bit obscure (for example in that there are MANY different dialects of it), it's nice and useful but also a bit niche. Only consider it if you know a bit what's going on and you have a special reason you'd want to learn it (for example if you're an [Emacs](emacs.md) user).
- [Assembly](assembly.md): Really, really hardcore choice, only for the most oldschool masochists who want to learn programming like they did back in the 1960s, from the very [bottom](low_level.md) up. This will be yet harder than C. Probably only consider this if you know you're a borderline genius and love to fiddle with computers at very low level, messing with [hardware](hw.md) and [electronics](electronics.md). Basically if you're aiming to making your own computer from the ground up.
- [PHP](php.md): Just to offer yet more choice, however PHP is rather discouraged as it's not a super nice language and is also not as much used anymore. It's simpler than C, in the league of simpler languages, and will allow you to program server side stuff, so maybe look into it if you want to make things on the web, like turn-based browser games or search engines.
- [Go](golang.md): Rather discouraged but offered for more variety, it will be on the level of C and is actually marketed as "new C", however it has some [modern](modern.md) shit, really only consider Go if for some reason you want to learn a harder, lower level language while really really refusing to learn the other languages like C and Pascal for some weird reason.

{ 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. ~drummyfish }

**[Games](game.md) are an ideal start [project](project.md)** 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 safest choice as a first project -- if you are feeling more ambitious, try to write the same thing but in [C](c.md). Once you're more comfortable you may consider to start using graphics, e.g. Python + [Pygame](pygame.md) (or, again, C + [SAF](saf.md) or [SDL](sdl.md) if you want a better language), 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 AND, by having weak hardware, not allowing you to write shitty code. Whatever language you start with, it is unavoidable that one day you will have to make the big step and **learn [C](c.md)**, the most important language as of yet, but if you see you're struggling with a simpler language, be sure to only start learning C 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.

As with all, you learn by doing -- reading is extremely important and necessary, but to actually learn anything well spending thousands of hours practicing the art is paramount. So **program, program and program**, live by programming, look for ways of using programming in what you're already doing, try to automate anything you do, think about programming before sleep etc. If you can, **contribute to some project**, best if you can help your favorite [FOSS](foss.md) program -- try this at least once as being in the company of the experienced just teaches you like nothing else, a month spent contributing to a project may be worth two or three years of just reading books. If you're [extremely asocial](avpd.md), the alternative is to just [fork](fork.md) someone else's program and trying to modify it -- this way you'll at least learn to understand someone else's code and you'll see how someone experienced writes the code.

### Programming Tips

This section will contain additional useful tips for programming.

- **Add by small steps**, spare yourself [debugging](debugging.md) hell later, do one step after another (see also [orthogonality](orthogonality.md)): when adding features/functionality etc. into your code, do it by very small steps and test after each step. Do NOT add multiple things at once. If you add 3 features at once and then find out the program doesn't work, you will have an extremely hard time finding out the bug because it may be in feature 1, feature 2, feature 3 or ANY COMBINATION of them, so you may very well never find the bug. If you instead test after adding each step, you find potential bugs immediately which will make fixing them very quick and easy.
- **Program on a weak computer** or alternatively use some utility such as [cpulimit](cpulimit.md) to make your hardware weaker, this will help you make your program efficient (and learn [how to do it](optimization.md)), any inefficiency will be immediately apparent as your program will simply run slow or swap. Using a physically weak computer is best as it is limited in all aspects so it will also help you make the program easy to develop on such computer etc., small [embedded](embedded.md) devices such as [open consoles](open_console.md) are ideal.
- **Jerk off before programming**: This will make you think less about sex and focus better.
- **No indentation for temporary code**: Tiny "workflow" tip: when adding new code, keep it unindented so that you know it's the newly added code and can delete it at any time. Only when you test the added code, indent it correctly to incorporate it as the final code. Of course, this fails in languages where indentation matters ([Python](python.md) cough cough) but similar effects can be achieved e.g. by adding many empty lines in front of/after the temporary code.
- **[Comments](comment.md)/[preprocessor](preprocessor.md) to quickly hide code**: It is a basic trick to comment out lines of code we want to temporarily disable. However preprocessor may work even better, e.g. in C if you want to be switching between two parts of code, instead of constantly commenting one part and uncommenting the other just use `#if 0` and `#else` directives around the two parts. You can switch between them by just changing 0 to 1 and back. This can also disable parts of code that already contain multiline comments (unlike a comment as nested multiline comments aren't allowed).
- **[KEEP IT SIMPLE](kiss.md)** and keep it [LRS](lrs.md), do not blindly follow mainstream ways and "workflows" as those are more often than not horrible. For example instead of using some uber bug tracker, you should use a simple plaintext TODO.txt file; instead of using and IDE use [vim](vim.md) or something similar. Stay away from [OOP](oop.md), [dependencies](dependency.md) etc.
- **It's hard, but you MUST adopt good minimalist tools, avoid the easy path of big shiny "comfortable", easy-to-learn [IDE](ide.md)s and languages**: this must come naturally with [LRS](lrs.md) mindset but still can't be overstressed because nowadays you'll be constantly pressured to start using this newest [modern](modern.md) [GUI](gui.md) programming tool with [AI](ai.md) assistant and nodes programming and zoomable code minimap that has a debugger and space rockets built right but succumbing to the pressure is short sighted and will reduce you to a zombie, a mere [coding](coding.md) monkey, you'll never actually acquire true control, understanding and craftsmanship, you'll just become a well paid button pressing slave no different from the cashier at a supermarket. It is difficult to learn tools like [vim](vim.md), [gdb](gdb.md), [C](c.md), [Forth](forth.md), [assembly](assembly.md) etc., but it's required in order to become a truly good, independent programmer, you will probably have to FORCE yourself to it, but it's the best investment of your time and energy: it's a long term investment you will later on thank yourself for. Choosing the more difficult but long-term-valuable road must become henceforth your mindset, this will apply whenever you can comfortably use a library or rather invest more energy into learning the math and programming your own library -- this is the difference between someone who uses a translator app on his smartphone and someone who learns to speak the foreign language, it's the difference between a computer slave and a good programmer.
- **Never listen to advice of anyone who does programming for living** (not [anymore](21st_century.md)), he's most definitely accustomed to the worst ways of programming and will try to push you to [OOP](oop.md), [bloat](bloat.md), [proprietary](proprietary.md) tech, [tranny software](tranny_software.md), [GitHub](github.md) etc. Listening to advice of such people is like taking advice on whether to take drugs from a drug dealer.
- **Most true programming is done away from the computer** -- soydevs think that a good programmer just spends hours in front of a computer bashing the keyboard and drinking litres of coffee to stay alive and [PRODUCTIVE](productivity_cult.md); indeed, they usually do, but they are not good programmers, their time is spent slaving the computer doing [maintenance](maintenance.md), debugging, googling, updating and socializing on Twitter. A good programmer actually programs everywhere: when going for walk, before falling asleep, when sleeping, when watching a movie etc. He only starts writing a serious program after years of thinking about it and already having most of it programmed in his head; sitting in front of a computer and writing the algorithm down is only the final smaller part of the journey.
- It can't be repeated enough times: minimize ALL kinds of [dependencies](dependency.md), don't use what you don't necessarily need -- this doesn't just apply to libraries but also design decisions. E.g. if you're making a compiler, make it a single pass compiler if at all possible, don't perform several source code passes if that's not absolutely necessary (which would however likely signify some flaw in the design of your language). Use [fixed point](fixed_point.md) instead of [floating point](float.md) if you can, [software rendering](sw_rendering.md) instead of GPU rendering etc. If you're making something that transforms text to another text (e.g. machine translation), make it a [filter](filter.md) with constant memory complexity if that's possible, i.e. do not require the program to load a whole input file to memory. Etcetc.
- During development turn off optimization flags for faster compiling and turn on verbosity and various checks, e.g. `-Werror -Wall -Wextra -Wpedantic` for [C](c.md).
- By [Unix philosophy](unix_philosophy.md) **don't be afraid to throw away your code and start over and better** -- next time you'll most likely write the same program a lot better and if you're a Unix programmer, your programs are small, possible to be reimplemented quicky. This has even been generalized into a wisdom that says "plan to throw away one", i.e. when approaching a new issue, you quite frequently start writing a program you know you will throw away when it's finished, just to start over and better; the first program just serves to help you understand the true essence of the problem and foresee the real problems you will face.
- **Go out!** This is related to the other point -- you shouldn't just sit at the computer when programming, get up and go for a walk, do something else, take a shower, go swim, do something in the garden, repair some stuff or something like that. Fresh air and sunlight helps the brain, it makes you feel better and it's been shown that walking helps activate some important brain centers, many people [actually](ackchyually.md) say they have to walk when thinking hard { Can confirm. ~drummyfish } Changing your environment and getting out of the current focus on the letter on the screen can kick off some real great idea, seeing seemingly unrelated things in nature can spark some inspiration. If you're stuck, take a day off, just sleeping and approaching the problem fresh does miracles. This really does help. It may help to **carry around a blog for taking notes** so that you don't have to stress about forgetting the ideas -- prefer paper blog, leave all electronics at home.
- Insert funny [hexadecimal](hexadecimal.md) constant in your program such as `0xED1B1EFAECE5`.
- TODO: moar

## See Also

- [computer science](compsci.md)
- [programming language](programming_language.md)
- [mathematics](math.md)