SERVING THE QUANTITATIVE FINANCE COMMUNITY

  • 1
  • 3
  • 4
  • 5
  • 6
  • 7
  • 16
 
User avatar
Cuchulainn
Topic Author
Posts: 63263
Joined: July 16th, 2004, 7:38 am
Location: Amsterdam
Contact:

Architecture and Design

October 23rd, 2011, 4:48 pm

QuoteOriginally posted by: outrunWhat's 'just programming'?When I am testing a new algo or whatever I just program it without any OO push-pash. Usually namespaces, function ptr stuff.Just programming can also mean hacking without a good design up-front.
Last edited by Cuchulainn on October 22nd, 2011, 10:00 pm, edited 1 time in total.
Chips chips chips Du du du du du Ci bum ci bum bum Du du du du du Ci bum ci bum bum Du du du du du
http://www.datasimfinancial.com
http://www.datasim.nl
 
User avatar
Polter
Posts: 2526
Joined: April 29th, 2008, 4:55 pm

Architecture and Design

October 23rd, 2011, 4:50 pm

I think outrun has in mind design principles along the lines delineated by the author of Breaking Up The MonolithQuoteBreaking Up The Monolith describes techniques for writing and working with C/C++ libraries effectively, efficiently and with minimal coupling.It illustrates how to write high-quality C++ software that does not need to sacrifice on important software quality characteristics such as robustness, performance, expressiveness, flexibility, modularity, portability, and discoverability & transparency.The principles of C++ software engineering espoused in this book are:- Software quality is important, and compromise should be, and can be, minimized. Compromise on robustness is not allowed- C++ is hard, so only use it when you must- The only significant reason to use C++ is performance- Choose C++ over C for expressiveness and resource management- To write C++ without regard for its performance is a manifest waste of time- Designing for speed does not mean that you must lose other aspects of software quality, nor is it a license to do so- Many C++ libraries, including parts of the C++ standard library, are not fit for purpose - There's no one true wayA good starting point is the prologue of "Extended STL, volume 1":http://synesis.com.au/publishing/xstl/x ... e.pdfSeven Signs of Successful C++ Software Libraries"Along with these principles, the material in this book (and in Volume 2) will be guided by the following seven signs of successful C++ software libraries: efficiency, discoverability and transparency, expressiveness, robustness, flexibility, modularity, and portability.""STL was designed to be very efficient, and if used correctly it can be, as we will see in many instances throughout this book. Part of the reason for this is that STL is open to extension. But it's also quite easy to use (or extend) it inefficiently. Consequently, a central aim of this book is to promote efficiency-friendly practices in C++ library development, and I make no apology for it. "He expands upon this in the series "Quality Matters".A good starting point for all of us (so we can all agree what we mean when we use certain terms -- right, outrun & Cuchulainn? :]):Quality Matters, #1: Introductions and NomenclatureQuoteIntrinsic Software Quality CharacteristicsTo be of any use, software quality characteristics have to be definable, even when the definitions involve relativism and subjectivity. To this end, I spent a deal of effort when writing my second book - <plug>Extended STL, volume 1: Collections and Iterators [XSTLv1]</plug> - considering the notion of quality for software libraries. I came up with seven characteristics of quality: Correctness/reliability/robustness Efficiency Discoverability and transparency Modularity Expressiveness Flexibility Portability See also the Breaking Up The Monolith / Glossary of Terms
Last edited by Polter on October 22nd, 2011, 10:00 pm, edited 1 time in total.
 
User avatar
Cuchulainn
Topic Author
Posts: 63263
Joined: July 16th, 2004, 7:38 am
Location: Amsterdam
Contact:

Architecture and Design

October 23rd, 2011, 4:55 pm

Polter,Maybe ISO 9126 is good. I use it as a sanity check.It is now for others to speak same lingo/vocabulary. Better than implicit internal models.QuoteI think outrun has in mind design principles along the lines delineated by the author of Breaking Up The MonolithFair enough. But remember rnorm's 3 layer model. Not everything is a library; and C++ is not the only language to support...BTW avoid monolith in design phase, in C++ it's too late. QuoteThe principles of C++ software engineering espoused in this book are:- Software quality is important, and compromise should be, and can be, minimized. Compromise on robustness is not allowed- C++ is hard, so only use it when you must- The only significant reason to use C++ is performance- Choose C++ over C for expressiveness and resource management- To write C++ without regard for its performance is a manifest waste of time- Designing for speed does not mean that you must lose other aspects of software quality, nor is it a license to do so- Many C++ libraries, including parts of the C++ standard library, are not fit for purpose- There's no one true way is this the infamous santy clause???This is a somewhat narrow and uncompromising viewpoint imo. (in ISO 9126, it is Efficiency..)
Last edited by Cuchulainn on October 22nd, 2011, 10:00 pm, edited 1 time in total.
Chips chips chips Du du du du du Ci bum ci bum bum Du du du du du Ci bum ci bum bum Du du du du du
http://www.datasimfinancial.com
http://www.datasim.nl
 
User avatar
Polter
Posts: 2526
Joined: April 29th, 2008, 4:55 pm

Architecture and Design

October 23rd, 2011, 5:13 pm

Cuch, yes, I think the principles delineated in ISO 9126 are very similar, perhaps more on a more general meta-level /* in particular, this is far more than solely efficiency -- I mentioned all seven principles for a reason; in particular, please note: "Designing for speed does not mean that you must lose other aspects of software quality, nor is it a license to do so" and continue reading, don't make premature judgements :-) */.The Quality Matters series is good, because it can serve as a bridge for a discussion that includes both you and outrun -- there's delineation of pure, abstract design principles and practical examples of how this applies to real C++ code and libraries (which makes those principles well-defined).http://www.quality-matters-to.us/
Last edited by Polter on October 22nd, 2011, 10:00 pm, edited 1 time in total.
 
User avatar
Polter
Posts: 2526
Joined: April 29th, 2008, 4:55 pm

Architecture and Design

October 23rd, 2011, 5:53 pm

+1 on STL conventions, in particular GP over OOP at a certain point (i.e., at least for (potentially) large K, M, N (objects, basic types, algorithms) -- very small (and guaranteed to remain so for eternity) K, M, N are perhaps more open to discussion and compromise) -- I think this is unavoidable if we want to avoid complexity and minimize coupling, otherwise we'd face the M*N problem:"For example, given N sequence data structures, e.g. singly linked list, vector etc., and M algorithms to operate on them, e.g. find, sort etc., a direct approach would implement each algorithm specifically for each data structure, giving N*M combinations to implement. However, in the generic programming approach, each data structure returns a model of an iterator concept (a simple value type which can be dereferenced to retrieve the current value, or changed to point to another value in the sequence) and each algorithm is instead written generically with arguments of such iterators, e.g. a pair of iterators pointing to the beginning and end of the subsequence to process. Thus, only N + M data structure-algorithm combinations need be implemented." // Generic programmingOr even K*M*N problem:"One of the main advantages of the use of generic programming is the significant reduce of code complexity. [...]Among of different programming paradigms the most interesting new paradigm is generic programming. The goal of this style is to reveal the foundations and programming methods of generic and therefore reusable components and libraries. In the terms of Multi-Paradigm theory we use generic programming in those cases when the objects have no or little common structure but the behavior (the methods used on objects) are similar. Using this approach we can greatly reduce the complexity of a software library. For example, if we have a library with n data structures, each with k base type and m algorithms, then using the traditional object-oriented way the complexity of the library is O(k*n*m). Using generic programming this reduced to O(n+m)." // Alternative Generic LibrariesA great concrete, practical illustration is Generic Programming and the Boost Graph LibraryThe object-oriented approach / " If we have M algorithms and N data structures, then we have O(M × N) code to write!"The generic programming approach / "We write O(M + N) code, leaving more time for skiing!"Now, it's true that at some point we still need to identify K, M, N -- I suppose on a very basic level this is where the layers enter. However, the design requirement that we minimize the coupling s.t. ++K, ++M, ++N remains !complex _supersedes_ the identification -- if we have a primary focus on "efficiency, discoverability and transparency, expressiveness, robustness, flexibility, modularity, and portability", we can have living libraries, like Boost. And then the identification of particular K, M, N can happen, say, one millisecond prior to its design and implementation.
Last edited by Polter on October 22nd, 2011, 10:00 pm, edited 1 time in total.
 
User avatar
Cuchulainn
Topic Author
Posts: 63263
Joined: July 16th, 2004, 7:38 am
Location: Amsterdam
Contact:

Architecture and Design

October 23rd, 2011, 6:01 pm

Sure, data structures should use GP. I agree 100%. But how can systems survive without run-time polymorphism?? QuoteThe generic programming approach / "We write O(M + N) code, leaving more time for skiing!"Or a 2nd edition of Siek et al
Last edited by Cuchulainn on October 22nd, 2011, 10:00 pm, edited 1 time in total.
Chips chips chips Du du du du du Ci bum ci bum bum Du du du du du Ci bum ci bum bum Du du du du du
http://www.datasimfinancial.com
http://www.datasim.nl
 
User avatar
Polter
Posts: 2526
Joined: April 29th, 2008, 4:55 pm

Architecture and Design

October 23rd, 2011, 6:08 pm

Well, not solely for data structures.It's not solely Containers<->Iterators<->AlgorithmsIt's also (for instance) Engines<->VariateGenerators<->Distributions: namespace boost { template<typename Engine, typename Distribution> class variate_generator;}http://www.boost.org/doc/libs/release/d ... e.concepts
Last edited by Polter on October 22nd, 2011, 10:00 pm, edited 1 time in total.
 
User avatar
Cuchulainn
Topic Author
Posts: 63263
Joined: July 16th, 2004, 7:38 am
Location: Amsterdam
Contact:

Architecture and Design

October 23rd, 2011, 6:13 pm

QuoteOriginally posted by: PolterWell, not solely for data structures.It's not solely Containers<->Iterators<->AlgorithmsIt's also (for instance) Engines<->VariateGenerators<->Distributions: namespace boost { template<typename Engine, typename Distribution> class variate_generator;}http://www.boost.org/doc/libs/release/d ... conceptsOk. I know Random. But when the number of parameters increases ==> GP breaks down (look at BGL, it's very difficult). It's like looking thru a telescope the wrong way around (for me). The whole design is flattened into a template parameter list (remember magic number 7, plus or minus 2?)For me, a pure GP is too rigid, as is pure OOP. We need a mix.Random is also a small library. It would be embedded in a larger framework. GP is not suitable for larger systems.
Last edited by Cuchulainn on October 22nd, 2011, 10:00 pm, edited 1 time in total.
Chips chips chips Du du du du du Ci bum ci bum bum Du du du du du Ci bum ci bum bum Du du du du du
http://www.datasimfinancial.com
http://www.datasim.nl
 
User avatar
Polter
Posts: 2526
Joined: April 29th, 2008, 4:55 pm

Architecture and Design

October 23rd, 2011, 6:29 pm

The slides from Boost Con are pretty good. Something worth noting:QuoteType Requirements and Concepts- The requirements of a template are expressed in terms of "concepts".- A concept is set of requirements.- When a particular type satisfies the requirements of a concept, we say that the type models the concept.This is very different from OOP. While on a surface there is a superficial semblance (and on that level one can think of classes-implement-interfaces as analogs of types-model-concepts), the way you approach this from a design level is very different (if not the opposite).Now, the obvious question is -- if the "requirements of a concept" are of such fundamental importance, where do we get them from? From the blue sky? Should we start with them like we used to start with the interfaces in OOP?An excellent exposition that provides the answers to those questions is that of Alexander Stepanov: STL and Its Design Principleshttp://www.stepanovpapers.com/stepanov-abstrac ... undamental Principles- Systematically identifying and organizing useful algorithms and data structures- Finding the most general representations of algorithms- Using whole-part value semantics for data structures- Using abstractions of addresses as the interface between algorithms and data structuresThe last two indeed focus on data structures, let's remember the first two here -- although we do have plenty of important domain-specific data structures to deal with, think option term sheets, etc.EDIT: let me elaborate upon that: where STL has Containers<->Iterators<->Algorithms, we may have, for instance, MarketData<->Pricers<->PricingAlgorithms.OptionTermSheet models MarketData.MonteCarloEngine models PricingAlgorithm.That OptionPricer models Pricer and needs to connect (work with both) OptionTermSheet and MonteCarloEngine follows from the conceptual requirements imposed on Pricers.This is where the fundamental difference is and I think this is what outrun is driving at (crucial: note the order -- in 1990s OOP it was more 3, 1, 2):QuoteIdentification and Organization1. Find algorithms and data structures2. Implement them3. Create usable taxonomyAgain -- note the order, contrast with OOP (and again I think that's what outrun is driving at) :QuoteGeneric Programming 1. Take a piece of code2. Write specifications3. Replace actual types with formal types4. Derive requirements for the formal types that imply these specificationsThe way one arrives at concepts in GP versus the way one used to arrive at interfaces in OOP is perhaps the most striking difference.Think about mathematics -- and contrast deriving a proof of a new mathematical theorem (where you _arrive_ at general concepts gathering the required assumptions on the go -- this is analogous to design of GP concepts) with presenting this proof in a mathematical journal (where you start with nicely stated assumptions that you specialize to get a proof -- this is analogous to design of OOP interfaces).Inductive reasoning versus deductive reasoning.With all that being said, I also agree you have a point on the importance of "late or early binding" -- see the part "Unifying OOP and GP" (in the talk).
Last edited by Polter on October 22nd, 2011, 10:00 pm, edited 1 time in total.
 
User avatar
Cuchulainn
Topic Author
Posts: 63263
Joined: July 16th, 2004, 7:38 am
Location: Amsterdam
Contact:

Architecture and Design

October 23rd, 2011, 6:36 pm

QuoteNow, the obvious question is -- if the "requirements of a concept" are of such fundamental importance, where do we get them from? From the blue sky? Should we start with them like we used to start with the interfaces in OOP?Well-known.aka what are the provides/requires interfaces between components. During detailed design you can choose betwen GP, OOP or even procedural.BTW the answer to your question is my input. Move up one knotch from C++. Find bespoke interfaces then map to C++.//Concepts implement 'requires' interfaces. You can do it on OOP as well, e.g. C# constraints.
Last edited by Cuchulainn on October 22nd, 2011, 10:00 pm, edited 1 time in total.
Chips chips chips Du du du du du Ci bum ci bum bum Du du du du du Ci bum ci bum bum Du du du du du
http://www.datasimfinancial.com
http://www.datasim.nl
 
User avatar
Polter
Posts: 2526
Joined: April 29th, 2008, 4:55 pm

Architecture and Design

October 23rd, 2011, 6:48 pm

QuoteFind interfaces then map to C++.Well, no, that would be precisely starting from #3 (the OOP way). Start from #1. Take a piece C++ code, note the required assumptions, and map to concepts (the GP way). Perhaps I need to work on my communication skills if I'm failing to get this point across :-(outrun? Again, let me emphasize the implications on the happens-before relationships:QuoteIdentification and Organization1. Find algorithms and data structures2. Implement them3. Create usable taxonomyImplication: implementation happens-before taxonomy.Elaboration: one cannot talk about taxonomy without having implementation in mind.QuoteGeneric Programming 1. Take a piece of code2. Write specifications3. Replace actual types with formal types4. Derive requirements for the formal types that imply these specificationsImplication: a piece of code happens-before specifications. Elaboration: one cannot talk about specifications without having a piece of code in mind.Yes, I realize that both GP and OOP are ways of arriving at abstractions, but the order in which this arrival happens in the design process is quite different.
Last edited by Polter on October 22nd, 2011, 10:00 pm, edited 1 time in total.
ABOUT WILMOTT

PW by JB

Wilmott.com has been "Serving the Quantitative Finance Community" since 2001. Continued...


Twitter LinkedIn Instagram

JOBS BOARD

JOBS BOARD

Looking for a quant job, risk, algo trading,...? Browse jobs here...


GZIP: On