Better Software - June 2008 - (Page 15) Code Craft template class Composer { private: typedef typename iterator_traits ::value_type Fun; typedef typename Fun::result_type T; typedef reverse_iterator RevIter; RevIter beg, end; static T apply(T sofar, Fun f) { return f(sofar); } public: Composer(Iter b, Iter e) : beg(RevIter(e)), end(RevIter(b)) {} T operator()(T x) { return accumulate(beg, end, x, apply); // Function Applicator } }; Listing 3 main in listing 5, two unnamed functions are created and stored in funs. The variable c holds the delegate returned by the call to compose. So T delegate(T) compose(T)(T function(T)[] funs) { T doit(T n) { T result = n; foreach_reverse (f; funs) result = f(result); return result; } return &doit; } Listing 4 what is a delegate in D? It is the very mechanism that allows funs to persist and be used by the instance of doit returned by a call to compose. A delegate is a pair that contains a pointer to a function (which could be a class method) and the calling context of the function. That calling context could be an activation (stack frame) of an enclosing function, as compose is for doit, or it could be an object or class used as context for a method. So that its calling context—the activation of the call to compose—is preserved for doit to do its work, doit must be returned as a delegate. That context is preserved even after com- pose has terminated. Such a persistent calling context is called a closure. The closure for compose is moved from the runtime stack to the garbage-collected heap so it persists as long as the variable c in listing 5 does. There is no need to create a class to solve this problem, and the nested-function approach is simpler anyway. Whither Function Objects? C++ popularized the use of function objects—sometimes called functors—with the introduction of STL. A function object is nothing more than an instance of a class that overloads the function-call operator. To illustrate, listing 6 creates a C++ function object, gtn, which determines whether its argument is greater than a previously stored value. Similar code can be written in D using the opCall special function, but the nested-function version in listing 7 is simpler. Once again we have an outer function that returns a nested function that has access to the outer calling context. It appears that nested functions and closures can replace function objects template class gtn { T n; public: gtn(T x) : n(x) {} bool operator()(T m) { return m > n; } }; int main() { gtn g5(5); cout<< g5(1) <<endl; cout<< g5(6) <<endl; } Listing 6 pointer to the function doit. The function doit itself uses the array funs, which is defined in compose’s parameter list. It is common to say that funs is in the “calling environment” of doit. So what happens when a pointer to doit is returned from a call to compose? In order for funs to persist for use by subsequent calls to doit, it has to somehow be saved and connected to doit. Consider how compose is used in listing 5. The function keyword has two related uses in D: to declare a function pointer and to define an anonymous function literal (like “lambda” expressions in functional programming languages). The first usage occurs in the definition of compose in the first line of listing 4 and also in the first line inside main in listing 5. In each case, funs is declared a dynamic array of single-valued function pointers. In the second and third lines of import std.stdio; void main() { int function(int)[] funs; funs ~= function int(int x){return x*x;}; funs ~= function int(int x){return x+1;}; auto c = compose(funs); writeln(c(3)); // 16 } Listing 5 // false // true www.StickyMinds.com JUNE 2008 BETTER SOFTWARE 15 http://www.StickyMinds.com
Table of Contents Feed for the Digital Edition of Better Software - June 2008 Better Software - June 2008 Contents Mark Your Calendar Contributors Technically Speaking eLightenment Code Craft Test Connection Management Chronicles Agile Model-Driven Development The Myth of Risk Management Stop the Insanity! Product Announcements 10 Things You Might Not Know About … The Last Word Ad Index Better Software - June 2008 Better Software - June 2008 - (Page Intro) Better Software - June 2008 - Better Software - June 2008 (Page Cover1) Better Software - June 2008 - Better Software - June 2008 (Page Cover2) Better Software - June 2008 - Better Software - June 2008 (Page 1) Better Software - June 2008 - Better Software - June 2008 (Page 2) Better Software - June 2008 - Contents (Page 3) Better Software - June 2008 - Mark Your Calendar (Page 4) Better Software - June 2008 - Mark Your Calendar (Page 5) Better Software - June 2008 - Mark Your Calendar (Page 6) Better Software - June 2008 - Mark Your Calendar (Page 7) Better Software - June 2008 - Contributors (Page 8) Better Software - June 2008 - Contributors (Page Telelogic1) Better Software - June 2008 - Contributors (Page Telelogic2) Better Software - June 2008 - Contributors (Page 9) Better Software - June 2008 - Contributors (Page 10) Better Software - June 2008 - Technically Speaking (Page 11) Better Software - June 2008 - eLightenment (Page 12) Better Software - June 2008 - eLightenment (Page 13) Better Software - June 2008 - Code Craft (Page 14) Better Software - June 2008 - Code Craft (Page 15) Better Software - June 2008 - Code Craft (Page 16) Better Software - June 2008 - Code Craft (Page COD1) Better Software - June 2008 - Code Craft (Page COD2) Better Software - June 2008 - Code Craft (Page COD3) Better Software - June 2008 - Code Craft (Page COD4) Better Software - June 2008 - Code Craft (Page 17) Better Software - June 2008 - Test Connection (Page 18) Better Software - June 2008 - Test Connection (Page 19) Better Software - June 2008 - Management Chronicles (Page 20) Better Software - June 2008 - Management Chronicles (Page 21) Better Software - June 2008 - Agile Model-Driven Development (Page 22) Better Software - June 2008 - Agile Model-Driven Development (Page 23) Better Software - June 2008 - Agile Model-Driven Development (Page 24) Better Software - June 2008 - Agile Model-Driven Development (Page 25) Better Software - June 2008 - Agile Model-Driven Development (Page 26) Better Software - June 2008 - Agile Model-Driven Development (Page 27) Better Software - June 2008 - Agile Model-Driven Development (Page 28) Better Software - June 2008 - Agile Model-Driven Development (Page 29) Better Software - June 2008 - The Myth of Risk Management (Page 30) Better Software - June 2008 - The Myth of Risk Management (Page 31) Better Software - June 2008 - The Myth of Risk Management (Page 32) Better Software - June 2008 - The Myth of Risk Management (Page 33) Better Software - June 2008 - The Myth of Risk Management (Page 34) Better Software - June 2008 - The Myth of Risk Management (Page 35) Better Software - June 2008 - Stop the Insanity! (Page 36) Better Software - June 2008 - Stop the Insanity! (Page 37) Better Software - June 2008 - Stop the Insanity! (Page 38) Better Software - June 2008 - Stop the Insanity! (Page 39) Better Software - June 2008 - Stop the Insanity! (Page 40) Better Software - June 2008 - Stop the Insanity! (Page 41) Better Software - June 2008 - Stop the Insanity! (Page 42) Better Software - June 2008 - Stop the Insanity! (Page 43) Better Software - June 2008 - Product Announcements (Page 44) Better Software - June 2008 - Product Announcements (Page 45) Better Software - June 2008 - 10 Things You Might Not Know About … (Page 46) Better Software - June 2008 - The Last Word (Page 47) Better Software - June 2008 - Ad Index (Page 48) Better Software - June 2008 - Ad Index (Page Cover3) Better Software - June 2008 - Ad Index (Page Cover4)
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.