Table of Contents for Programming Languages: a survey

Part IV: Idioms, patterns, and best practices


strategy pattern

factory pattern

inversion of control (a form of inversion of control)


two-way model binding

futureproofing patterns

(cross-reference extensibility)

points out three kinds of futureproofing in java:

these are all annoying boilerplate, but they are all good things to do because if you don't, and you want to make one of the following changes, then you must change every call site, instead of just one line. This is especially bad if your program is a shipped library and the call sites are in client code (e.g. you would have to make breaking/incompatible changes to your library):

now, Jasper already deals with the first two of these, and maybe the third. If not, We should probably deal with the third, too. That is to say, when you call a constructor (if we have constructors at all; i'm leaning towards yes), you don't actually determine an implementation but merely an interface, and perhaps a factory method to determine the implementation. In other words, 'everything is an interface', like we always say.

in, he also points out a few more that Go handles that Java doesn't:

in, he also points others kinds of futureproofing that aren't needed in Java but that may be needed in other languages, such as Go:

book rec: design patterns


"By default you should compile with optimization on. Forcing the compiler to work harder helps itfind more potential problems." --


C++'s rule of three:

prefer STL vectors rather than raw arrays --

don't prefix variable names with _ b/c this may conflict with some "reserved naming conventions for C, Posix, and/or compilers" --

"A nice rule of thumb is to always write the member initializers in the order they are defined." --

compile with -Wall and usually -Wextra-pedantic and -Weffc++ as well --

write constructor initializers in the order they will be evaluated --

don't make any functions virtual in a class unless you are designing the class to be inherited from --

be careful to use delete[] when appropriate, e.g. when you used new[] to allocate

Chapter: Types of coding tasks

numeric linear algebra:

operator overloading is crucial


memory footprint is crucial (often, GC isn't good enough, e.g. Objective-C)

hobby project:

little boilerplate; no need for team features

simulation: CPU-bound; speed; OOP; parallelism

Concurrency patterns

overuse of synchronization leads to throwing away a lot of concurrency. advanced algorithms such as lock-free algorithms accept/permit nondeterminacy as much as possible during their execution, but still give deterministic results at the end. but they are difficult to write/reason about.

if using basic locking, where to lock in data structures (e.g. to create critical sections): create a critical section out of any piece of code s.t. if you stopped in the middle, an invariant would be violated; or any piece of code s.t. if another thread updated shared memory in the middle, there would be a problem.

beware: returns, gotos, possible exceptions; anything that could interrupt you

beware: function calls that might call something else that would block on one of the locks you've acquired

POSIX, pthreads

design criteria for programs