8 Programming Components
18 September 2024
Questions?
5min
Where we are We have looked at:
spiral analysis of the problem space, use cases
component identification and planning
component interfaces: what kind of services do components provide
It is time to look at the how components are made in a socially responsible manner. This is where 80% of socially responsible sw dev happens.
Meta-how: how do you write down the how—
8.1 Clarity of Code
5min
Factors involved:
Comments A typical response to “I don’t understand this code” is to say “we’ll add comments” or, to sound sophisticated, the sw dev may say “we’ll add documentation.” What does this mean?
Names One of the most basic and helpful changes to code is to use good names for interfaces, classes, fields, methods, parameters, and variables. How do we make names signal their role inside of code?
Data representations Choosing a weil-suited data representation is the most difficult step. It has implications for several other aspects, including names, comments, and methods. How do we pick good data representations?
Size of Units of Code, esp. Methods Conquering complexity means keeping units of code small so that they become easily comprehensible. Methods (or functions) are the most basic units of code. How do we keep them small enough? What is small?
8.2 Comments
10-15min
Every programming language comes with a mechanism for adding comments to code. That does not tell us how to use this mechanism to convey important supplements to code.
Comments are almost always wrong. Out of sync.
x = x + 1; // increase x by 1 |
One cure: write down comments that play a specific roles:
interpretation statements for the chosen data representations
physical units, reaction to changes
purpose statements of methods in interfaces (what do they do)
when it takes just too many chars to give a name to a method that tells the reader what it does
field int distance_of_left_front_corner_of_vehicle_to_the_object_tn_the_left_of_the_car_in_meters = 0;
// which parts should go into the name, which into the purpose statement
special functions and constructs: termination statements for gen rec functions; accumulator statements for while loops and accumulating functions; when the “how” is hard.
8.3 The Very Basics
Three aspects of code influence comprehensibility of methods and functions: (use of) names; size of methods; conditionals.
8.3.1 Names
10min
re-use the above example to address the issue of which parts go into a name, which into a purpose statement
if metric units matter, make it part of the name
if the exact location matters, ...
Give meaningful names to intermediate results:
|
|
|
8.3.2 Size of Functions and Methods
15-25min
Squeak is an implementation of a programming language like Java w/o types. Its core is 600,000 lines of code as of 2020. It is written in the Squeak itself. Guess how long the average method is?
Six (6) lines of code.
How did they achieve this? They followed the advice we start giving you in Fundamentals I:
each function should perform one computational task and otherwise use function composition
or
a function composes several tasks via function calls (functional design), semicolon, looping and case distinction
and
a function performs a basic, atomic task.
In Fundamentals I structurally recursive functions and functions on structures are egood examples.
Sample problem:
Develop a program that, given an input-file name and an output-file name, consumes the content of the input-file of JSOn values (up to 1K, only Strings, Numbers, Objects, and Arrays), turns them into numbers, and writes out the resulting sequence of numbers as a JSON array of corresponding strings to the output-file.
Each JSON value is turned into a number as follows:
strings – the number of chars in the string
numbers – easy
objects – the sum of the field values turned into numbers
arrays – the product of the values of its elements
Work through this, explain how each function stays small. Explain one more time how someone chose a data representation for JSON values
#; {PathString PathString -> Void} ; composite (define (main in-file-name out-file-name) (define in (read-in-file file-name)) (define numbers (turn-into-numbers in)) (define strings (as-strings numbers)) (write-as-json-file strings out-file-name)) #; {PathString -> [Listof JSexpr]} ; atomic: use library (define (read-in-file in) '[]) #; {[Listof String] PathString -> Void} ; atomic: use library (define (write-as-json-file strings out-file-name) (void)) #; {[Listof JSexpr] -> [Listof Number]} ; use recursion to match structure JSexpr (define (turn-into-numbers in) '[]) #; {[Listof Number] -> [Listof String]} ; use for loop ‘(for/list (...) ..)‘ (define (as-strings numbers) '[])
Total: 35–60 mins