1. Top-Down Design
Most of the problems in the SICP book are solved in a top-down way with lower level details deferred until needed. The focus on high-level details makes for expressive, flexible code since implementation is based on well-defined interfaces and not implementations. Consequently, swapping and improving interfaces is a cinch – the dependency on high-level interfaces shields consumers from tight coupling to details.
Picture a calculus system for integer operations (e.g., differentiation); as expected, these higher-order functions need support for addition/subtraction/division operators. A top-down design will implicitly assume the add/subtract operators will work appropriately and focus on the higher-level operators first. These low-level details can even be mocked, and the system unit tested to prove logic accuracy.
The benefit of such a delayed implementation comes when the system needs to be extended to support complex numbers—the higher-level operations remain the same; only the low-level add/subtract operators need to be changed. Once this is done, the entire system should work as before.
Design is subjective, and this is one approach; there might be better ways for other scenarios, but this can be tried and leveraged again.
2. Generics: Data-directed vs Message-Passing Styles
Generics are useful for maintaining and extending existing systems.
The data-directed style maintains a huge table of known procedures and determines desired operations based on keys. Extending such systems involves adding the new function signatures to the table; this allows the entire system to start using the newly added functions (sounds like the adapter pattern).
The downsides include the extra overhead of a procedures table, the need for consumers to know about available operations, and the enforcement of contracts in the system. However, benefits such as flexibility, encapsulation, and ease of accretion of new features can’t be ignored.
Message passing involves sending messages to objects to trigger the right operations. Sounds familiar? Yes, it does sound like OOP and is one of its major tenets. An object keeps a list of possible operations and invokes the right method based on the message it receives (think of invoking an instance method in an OOP language as sending a ‘message’ to the object e.g. a.b() ).
Languages like Python and JavaScript allow for a clearer example of the message passing metaphor since they allow creating hashtables of functions. With such a hashtable, you can invoke a function by sending a ‘message’ to such functions e.g. a[“b”]().
Thus, the question arises: How do programming languages handle their primitive operations at a lower level? Do they do message passing? Keep tables?
Don’t miss the next post!
Subscribe to get regular posts on leadership methodologies for high-impact outcomes.
3. Context
The importance of context and how it affects semantics in all languages (both human and programming).
Using the book’s example, three equals one plus two; however, ‘three’ is not equal to “one plus two.” The context determines what is meant, and humans have long used this to create various literary forms, such as puns, sarcasm, etc.
The same applies to programming. Context determines whether your program will run perfectly or have subtle but difficult-to-find errors. One obvious example is JavaScript, which follows this pattern.
4. Huffman Encoding
Some computer science and maths, eh? The Huffman encoding scheme allows you to use much less space, provided the conditions are met.
5. Understanding the problem deeply before writing any code
Coding should be simple. Unfortunately, a shallow understanding of the problem being solved makes it a difficult task.
Spending a good chunk of time understanding the programming task has great benefits. It leads to well-thought-out designs, simple models (simple is difficult!), and fewer bugs. It also reduces the chances of providing the wrong solution. It also makes for a more fulfilling experience—what beats the thrill of having zero compile errors on the first attempt?
If you liked this post, then do check out a couple more exciting discoveries from my SICP journey:
1. SICP Section 2.2: New ideas and thoughts about programming
2. SICP Section 2.1: Thoughts
3. SICP Section 1.3: Thoughts and Concepts
Don’t miss the next post!
Subscribe to get regular posts on leadership methodologies for high-impact outcomes.
Discover more from CodeKraft
Subscribe to get the latest posts sent to your email.