4 ms·
There is much to learn from Dijkstra since Human nature is not that very different. Problem-solving requires a multifaceted approach and if we find that somebod
by rramadass 3y ago
There is much to learn from Dijkstra since Human nature is not that very different. Problem-solving requires a multifaceted approach and if we find that somebody had used a Method/Process which gave them exceptional results then we need to extract the essence of their methodology and learn to apply them in our own individual contexts.
As an example w.r.t Dijkstra's "working habits" here are my takeaways;
1) His focus on logical rigor in thinking of a Program as a sequence of "Predicate Transformers" (https://en.wikipedia.org/wiki/Predicate_transformer_semantics https://en.wikipedia.org/wiki/Predicate_transformer_semantic...) is very fundamental to thinking about programming. Even if i do not use his particular notation/techniques, cultivating the habit of thinking about logical predicates operating in the state space of the program before writing the code which moves the state space from one to another i.e. from Pre to Post condition is essential to writing correct programs.
2) His emphasis on writing everything down by hand before touching a computer. The biggest problem facing a Programmer today is myriads of distractions hindering any attempt to focus and think for long stretches of time consistently. If you sit with paper/pencil and force yourself to think and write out your thoughts/algorithms then the above problem goes away. He famously wrote the THE OS by hand!
3) Learn to focus only on the absolute essentials and not on accessories like IDEs/debuggers/etc. Dijkstra famously stated that programming should only be taught in a precise language for which there are no compilers to machine code in order to force students to "play computer" and think through their program execution. Tools should be used only to augment thought but never to supplant/short-circuit it.
If you look at the working habits of the great Scientists/Geniuses almost without exception they avoided "busyness", ruthlessly cut out all inessentials from their work, wrote precisely, used tools judiciously and thought deeply. This is what we need to hold on to in this day and age where we have a surfeit of everything (distractions, tools, socializing etc.) designed to hinder us at every turn.
- nordsieck 3y agoA counterpoint to your second point is Gall's law: > A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over with a working simple system. https://en.wikipedia.org/wiki/John_Gall_(author) https://en.wikipedia.org/wiki/John_Gall_(author) At some point, problems are just too complex for any person, no matter how brilliant, to think through ahead of time. The only practical way to make progress on such problems is to implement a simplified version of a solution and then evolve it towards full function. Techniques like test driven development really embrace this idea.
- rramadass 3y agoI don't think this is actually contrary to my point (although it is just a heuristic). People completely misunderstand terms like "upfront design"/"waterfall model" nowadays. It does not mean that every facet of the system is nailed down "completely" before implementation. What it means is that the overall structure of the system is sufficiently clear with proper separation of concerns and modular boundaries to begin implementation. The design is "exact" at a high level but the details would be worked out iteratively. Top-down design and Bottom-up implementation. Dijkstra himself says this w.r.t. "Program Correctness" in his EWD288 "Concern for Correctness as a Guiding Principle for Program Composition". The same idea applies to design (replace "correctness proof" with "design" in the following excerpt). Finally, a word or two about a wide-spread superstition, viz. that correctness proofs can only be given if you know exactly what your program has to do, that in real life it is often not completely known what the program has to do and that, therefore, in real life correctness proofs are impractical. The fallacy in this argument is to be found in the confusion between "exact" and "complete": although the program requirements may still be "incomplete", a certain number of broad characteristics will be "exactly" known. The abstract program can see to it that these broad specifications are exactly met, while more detailed aspects of the problem specification are catered for in the lower levels.
- nordsieck 3y ago> What it means is that the overall structure of the system is sufficiently clear with proper separation of concerns and modular boundaries to begin implementation. The design is "exact" at a high level but the details would be worked out iteratively. Top-down design and Bottom-up implementation. With a complex enough problem, that doesn't work as well as you imply. The architecture that you come up with initially gets compromised by practical considerations. Which is the reason why re-implementations (often caused by changing languages for unrelated reasons) often result in substantially smaller code sizes because the second time around, the architecture is informed by the experience of implementation.
- rramadass 3y ago> With a complex enough problem, that doesn't work as well as you imply. No, the approach of breaking down a problem into smaller manageable pieces and attacking each piece separately in the same manner is universal. This of course will be guided by one's prior knowledge, experience and techniques to manage Risk. See for example the classic; The Spiral Model of Software Development - https://en.wikipedia.org/wiki/Spiral_model https://en.wikipedia.org/wiki/Spiral_model > Which is the reason why re-implementations ... because the second time around, the architecture is informed by the experience of implementation. True; but you don't get to do a re-implementation every time. Hence one has to evolve the system architecture carefully with the the same approach mentioned above.
- avg_dev 3y agoreally appreciate this post. 1) i did a quick skim of the predicate transformer wp page, looking at weakest preconditions and taking a short detour onto the definiton of hoare triples. i _think_ it is about minimal pre-statement (statement being the active code in question) assertions and maximal post-statement assertions and using that as a basis to define your program/algorithms. this leads to strong conclusions about the correctness of your code. i would say this is a great and perhaps necessary goal for important systems. i try to do it at a slightly higher and less rigorous level with automated tests, but the desire is the same, and if i really wanted correct code, i would probably do just this sort of thing. 2) i've been programming for a while. about a year and a half ago i noticed that i was falling into this bad habit that i had worked hard to get out of many years ago where i would just take a stab in the dark, tweak some code, and run my program over and over until the output was correct. :feelsbadman: since that time, i have made an effort to develop a habit of thinking much more before running my code, and it is showing results. often i can write code for hours, once recently i even did so for days, and not execute it, reasoning as much as possible about execution and state along the way, and when i finally run it, there are bugs but they are usually quite shallow and i can fix them quickly and then bam! it just works. sometimes i pause in this and for the satisfaction of running my new code i will write automated tests that check the correctness of some of the functionality. and i have paused at times and written in my notebook, explaining to myself what the problem is that i am trying to solve, why my current solutions have failed, and reasoning about what a good and working solution might look like, and designing it before opening the IDE. that works wonders too. i would say again - i'm not quite as rigorous as he was, but the method has helped me write better code. 3) yes, i have done this before, and i try to emulate the idea in my (high level) code. but i'm definitely not at that rigorous level :) and thank you for the reminder to avoid wasting time. Neil Gaiman has a speech called "Make Good Art" and i read the transcript (he has made a short book out of it) and watched a video of him actually delivering the speech at a graduation ceremony yesterday. i will conclude with a quote from that speech. > There was a day when I looked up and realized that I had become someone who professionally replied to email, and who wrote as a hobby. I started answering fewer emails, and was relieved to find I was writing much more.
- rramadass 3y ago