static modeling (& lifetime) using types to test, document and reduce system complexity

26
Static modeling (& lifetime) Using types to test, document and reduce system complexity

Upload: christopher-julius-williams

Post on 16-Dec-2015

219 views

Category:

Documents


0 download

TRANSCRIPT

Static modeling (& lifetime)Using types to test, document and reduce system complexity

Welcome

This talk/debate• Static modeling • Lifetime given time• Interrupt at any time!

Safety nets• Design/code reviews, pair programming• Compiler • Static modeling• Unit tests/module tests• Pipeline tests• Developer testing• Continuos integration• Static analysis tools (PCLint etc)• Dynamic analysis tools (Boundschecker, valgrind, etc)• QA testing• Design by contract• Assertions

Bold = expressed in code

Fail fast• Minimize turn around time – minimize waste• Bug found => ”Possible to catch earlier?”• Review => ”Possible to catch earlier?”

Failing fast in C++Build timeCode generationMacro expansionTemplate instantiationTranslation unit compilationLinking Installation/configuration

Run timeLoad timeStatic initializationBootstrapping/Initialization codeLevel load ... Specific/rare situations

Static modeling• Model invariants and tests with (static) types• Either compile time or instantiation time

int x=-10;bounded<int, -1, 99999> i(x);

quantity<speed> v = 1*meter/second;quantity<time> t = 2.0*minute;quantity<length> l = v/t;

Value of static modeling

1. Type up ASAP - fail fast2. Documentation3. Reduces complexity / state space

Code based tests

Static modeling, assertions, design by contract, automated test hooks, unit tests etc.

- Add ”weight” when prototyping+ ”Easy” to add to existing/legacy code

How to reduce the state space• Init/set/modify -> constructor/factory• Split objects into smaller pieces• Lock down dynamics ASAP

Demarshalling• Type up immediately

Indices• Indices only needed when de-/serializing• Look up immediately, pass around instance

Use typed ids

struct foo_id { int id; };bool operator==(...);

Distuinguish invalid ids by typeenum error {err1, err2};

class result { bool has_id(); const

/// @pre valid() foo_id get_id() const;

/// @pre !valid() error get_error() const;private: int data;};

result get_id(...);

// Using boostboost::variant<error, foo_id> get_id();

Optional

optional<X> find_closest_x();void do_stuff(const X& x);

• Isolate inited/not inited state• Clear semantics, all-or-nothing

bool find_closest_x(X& x);

Right/left hand system

Either compile time, runtime or combinedBetter granularity than math asserts on/off

RAII• new/delete • aquire/unaquire• connect/disconnect• lock/unlock• subscribe/unsubscribe• register/unregister• open/close

Need to match call pairs AND know if an objectis initialized or not

RAII example

void foo(int x, int y);

signal<void(int x, int y)> sig;signal_connection con(sig, foo);

Side note: RAII pillars• Exceptions• Deterministic destruction

Static modeling and lifetime• More work in constructor/destructor• Object lifetime becomes very important

Lifetime primitives• scoped_ptr (not copyable)• shared_ptr• weak_ptr• move_ptr (not copyable)• reference (not assignable)

Interfaceless objects/// @param foo is guaranteed to outlive/// return valuemove_ptr<void> create_stuff(const function<void()>& onBar,

shared_ptr<GuiFactories> gui,

const SomeFacade& foo, move_ptr<const ResourceX> x);

Summary• Static modeling pros: Fails fast, documentation, minimizes

total logic • Static modeling increasingly important in longer and larger

projects• Static modeling increases need of clear lifetime semantics

Static modeling vs. DbC

Catch errors that must be checked at runtime bytyping up or DbC/assertions?

• Is the invariant local?• Duplicate preconditions => time to type up!• S.M. only applicable to single variables

Opposite of static modeling

class message_channel{ void send(const string& key, const string& value); void listen(const string& key, listener& l) const;};

Dynamic modeling good for prototyping/iteratingOptimal: Lock down invariants in code by typing up

incrementally. No major language supports this well.

Don’t get lured by ”power”• Dynamic components are very powerful but can also be

abused• Specialized, less powerful = easy to understand and test,

smaller state space• Think reflection, introspection, tuple spaces