💾 Archived View for gemini.lostleonardo.xyz › sicp › lecture-2A.gmi captured on 2021-12-04 at 18:04:22. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2021-11-30)
-=-=-=-=-=-=-
Whenever you find yourself writing something more than once, you know that you are doing something wrong and you shouldn't be doing it. The reason why is because you are struggling to express an idea that could be expressed in a simpler way.
Whenever you try to make and understand complicated systems, it is crucial to divide things up into as many pieces as you can, each of which you understand separately.
"I would like to understand the way of adding up independently of what it is I'm adding up, so that I can reuse it, having debugged it once, having understood it once".
Whenever you have a bunch of things that are identical, it should tell you that you need to introduce some kind of abstraction.
In the previous lesson, you learned most of the syntax and the rules of Lisp, what you have not yet learned are common patterns of usage.
Most of the time, when you learn a language, you learn idioms, which are the common patterns of usage; the things that are useful to know in a flash.
In this language (Lisp), not only can you know those common patterns of usage (idioms), but you can give the knowledge of that pattern a name.
(DEFINE (<name> a b) (IF (> a b) 0 (+ (<term> a) (<name> (<next> a) b))))
What DEFINE does is it says, "Give this value a name, and here is the value".
(DEFINE <name> (<value>))
(DEFINE (sum term a next b) (IF (> a b) 0 (+ (term a) (sum term (next a) next b))))
'term' and 'next' are procedures for calculating something, in this case a number.
Taking a procedure as an argument to another procedures allows for the convenient decomposition of independent parts. In this case, it acts as a means of separating the things you are adding from the method of the addition. Abstraction should be a means of clarifying what it really going on.
The lambda notation can make it even clearer that one is dealing with a procedure that takes a procedure as its argument and produces a procedure as its value.
(DEFINE <name> (LAMBDA (<formal-parameter>) (<value>)))
Lambdas are very convenient for naming anonymous procedures, i.e. a procedure which produces a procedure as its value. Lambda notation also makes it clear that a procedure is an object that can be used as if it were any other value.
"Wishful thinking is essential to good engineering, and certainly essential to good computer science".
Procedures that take procedural arguments and produce procedural values provide a means of abstraction that helps to clarify complex programs.
Procedures that takes procedural arguments allow us to compress a lot of other procedures into one thing. It also creates a separation of concerns.
The rights and priveleges of first-class citizens (in a programming language) (Chris Strachey - inventor of denotational semantics)
Making functions first-class citizens allows you to make any abstraction you like.