⬆️ ⬇️

What I learned in programming

I have been programming for over 30 years. And my programming path stretches from Z80 and 6502 microprocessors to modern machines, from programming languages ​​such as BASIC, assembly, C, C ++ to Tcl, Perl, Lisp, ML, occam or arc, Ruby, Go, and so on.



Here is a list of what I learned in programming:



0. Programming is an artisan's lot, not a scientist or an engineer

')

Programming is more like a craft than a science or engineering discipline. This is a combination of skills and experience expressed in the ability to apply tools. The craftsman chooses the necessary tools (and if necessary, creates his own) and learns to use them.



For me it is a craft. I believe that the best programmers are closer to watchmakers rather than bridge builders or physicists. Of course, in appearance this occupation resembles science or engineering in the power of using logic and mathematics, but in most cases you just take the tools in your hands and create something.



If we take into account the fact that programming is a craft, it becomes immediately clear how important is experience, your tools and intuition.



1. Honesty is the best strategy.



When you write code, sometimes you are tempted to write a crutch and make the program work without a genuine understanding of what is actually happening. The classic example is when you decide to insert an API call simply because it magically fixes the bug; or when after inserting printf the program stops falling.



In both cases, there is self-deception. You have to ask yourself: “Do I understand why my program makes X?”. If not, then wait for trouble. Your task as a programmer is to understand what is happening because the computer does exactly what it says, and not what you think it should do.



Honesty requires diligence. You have to be meticulous and scrupulous when it comes to what your program does and why.



2. Simplify, simplify, simplify



Tony Hoar once said: “There are two approaches to programming. The first is to make the program so simple that there are obviously no errors in it. And the second is to make it so complicated that there are no obvious mistakes in it. The first is much more complicated. ”



Simplify, refactor, delete.



I would paraphrase Hoare’s statement: “Within each large and complex program there is a small, elegant program that does absolutely the same thing.”



This is akin to the " loosely connected building blocks " philosophy. It is much better to break the program into small parts that interact with each other than to build a solid monolith. UNIX, for example, owes its success in part to this approach.



3. Debuggers are crutches, profilers are not.



I almost never use the debugger. I write my programs so that they log all the necessary information on which you can understand what is happening. In most cases, I can understand what is wrong with the code for the log file without any help from the debugger.



The reason I rarely use the debugger is that it allows you to think less. Most people, when they find a bug, open the debugger and sink into the breakpoint of breakpoints, values ​​of variables and memory. What could be easier to fall under the spell of such a powerful tool, but if you put a little mind in the future it will pay off. If your program is so complicated that you need a debugger, you should refer again to point # 2.



(However, one of the most respected programmers by me, John Osterhout, seems to spend the whole day in the Windows debugger).



As for profilers, they are very useful if you need to evaluate performance. You will never stop wondering what interesting results the profiler gives you.



4. Duplication will have to be paid.



Do not repeat! In the code, do everything only once.



This is the point number 2, but here is a special case. Even a small piece of code that you have duplicated will lead to problems in the future when you change one version and forget to fix the second one.



5. Be illegible in languages



Some people are obsessed with one language and think that this language is suitable for anything. Wrong to think so. There is no language for all occasions.



The main thing is to understand which of the languages ​​among its tools to use for which problem. Therefore, it is better to have more tools. Try different languages, write something to them.



For example, you may not have to use many places in Python or ML, but you will work with list comprehensions and feel their power. Or play with Go and see how to work with competitive applications. Or you will work with Perl and appreciate the power of truly flexible working with strings. Finally, learn PHP to quickly create dynamic web pages.



I hate wars between languages. These wars are for losers because, in essence, there is nothing to argue about. For example, in my hands PHP is a disaster, whereas in other hands he will sing like a nightingale. This also applies to C ++.



6. Easier to build a program than to build it right away.



This item is closely related to item number 2. Start small and build on. When you solve a problem it is much easier to start with small blocks (perhaps making stubs for some parts) rather than design the architecture from beginning to end.



When you build architecture from start to finish, you 1) do it wrong 2) you end up with something big and complex where it will be very difficult to make changes. On the other hand, if you use small blocks that interact with each other, refactoring will be easier at the moment when you realize that you made a mistake at the very beginning.



The reason is that there is no way to find out what that proper architecture should look like. Only in rare cases, we can say what will be the external impacts on the program. You can say that you know the nature of the incoming TCP traffic that your mail server processes, or the number of users, or that you have never heard of spam. One way or another, there will be something from the outside that will completely destroy all your assumptions, and now if these assumptions concerned a big, strongly connected and complex system, you have big guy problems.



7. Learn how the layers are arranged.



I believe that it is extremely important to go up from the CPU to the language you use, to understand which layer is going on. It is very important to understand the layers (whether it is an understanding of what the C code compiles to, or in the case of Java, the understanding of the JVM and how it works).



This helps a lot when you are dealing with performance problems or debugging. A case pops up in my memory when a client sent us a screenshot of a crashing Windows 2000, which showed the state of a small piece of memory and registers. Knowing the version of the program installed by the client, we, only by this report, were able to identify the problem with a null pointer, and most importantly its reasons.



8. I am not so young to know everything.



I still have so much to learn. I hardly know some languages, although there is a desire to study them (Erlang, Clojure). Others I used, but I don’t know them so well (javascript). And also there are things that I understand with difficulty (monads).



PS I was accused of not saying anything about testing. It is worth adding that in my opinion tests are needed for any code that you have to deal with for a while. Maybe I need to program another 30 years and I will find the answer to the question “Does the unit improve software quality tests?”. I wrote the code both with and without unit tests, and I still do not know the correct answer, although I am more inclined to use unit tests.

Source: https://habr.com/ru/post/147722/



All Articles