Realizing C++11 Lambda Expression in Open64 Javed Absar

Anitha Boyapati

Dibyendu Das

AMD, India Richmond Road Bangalore +91 9901880710

AMD, India Richmond Road Bangalore +91 7795334034

AMD, India Richmond Road Bangalore +91 9448537014

[email protected]

[email protected]

[email protected]

ABSTRACT C++11 is the latest edition of C++ programming language standard by ISO. It replaces C++03. It includes a number of core language extensions, probably the most interesting of which is the inclusion of the lambda-expressions. The onus is now upon compiler writers – gcc, llvm, Open64 and others, to incorporate this extension into their existing compiler infrastructure so that programmers could benefit from this powerful language feature. Incorporating lambda-expression is not so straight-forward an extension for a compiler. It needs a good understanding of the C++11 standard and the many possible intricate use and misuse of this language feature in programs. In this paper, we analyze lambda expression from a language-feature perspective, the value it provides to programmers and how Open64 could support it.

Categories and Subject Descriptors D.3.4 [Programming Languages]: Processors – compilers.

General Terms Algorithms, Design, Languages and Theory.

Keywords lambda expression, anonymous function, C++11, C++0x, closure, higher order function, Open64, WHIRL, compiler.

1. INTRODUCTION C++11 [1] was approved by the ISO in August 2011 as the new standard for the C++ programming language, replacing C++03. The name C++11 is derived from the convention of naming language versions based on the year of publication. C++11 includes several addition to the core language. In the design of C++11 standard, the committee had applied some directives to help guide their decision. One of the directives was “to prefer changes that can evolve programming technique”. The inclusion of anonymous functions or lambda function is a direct result of that objective. Anonymous function is a function which is defined and invoked without being bound to an identifier. Anonymous functions have their origin in the works of Alonzo Church on -calculus [2][3]. They are a convenient way to pass functions as arguments to higher-order functions. Higher order functions are functions that take one or more functions as input and output a function as return value [4]. Their major use is to abstract common behaviour into one place [5].

Higher order functions are closely related to first-class functions. The distinction between the two is that higher-order function describes a mathematical concept while first-class object is a computer science term that describes programming language entity that has no restriction on its use. First-class functions can therefore appear anywhere in the program where other first-class entities such as numbers can appear, including as arguments to other functions and as the return value. In mathematics, higher order functions are also known as operators. For example, the definite integral in calculus is an operator that given a function f of a real variable x, and an interval [a, b] on the real line, returns the area under its curve. Later we will illustrate implementation of this operator using anonymousfunction construct of C++11. Anonymous function and lambda-expression are sometimes used in a mixed and confusing way, more so in programming language contexts than in mathematical expositions. In mathematics, lambda-expression is a notational convention in support of lambda calculus. Lambda expression in programming is an expression that specifies an anonymous function object [6]. Since anonymous functions in programming languages can have statements (control, assignment or expression statement) in the function body, the mathematical purity is lost to some extent. The first programming language to adopt anonymous functions was Lisp (1958). Traditionally anonymous functions have found good use in functional languages and languages that treat functions as first-class objects, such as Haskell, Scheme, ML and Lisp [7][8]. In the current era of multi-paradigm languages, many imperative, procedural and object-oriented languages have added anonymous class and anonymous functions to their repertoire of language features – C#, Clojure, Java, JavaScript, PHP, amongst others. C++ added anonymous function in its C++11 edition. Support for anonymous function in C# (.NET) [13] has improved with new versions of the compiler. In C# 1.0, one would create an instance of a delegate by explicitly initializing it with a method that was defined elsewhere in the code. In C# 2.0, a delegate could be initialized with inline code, called anonymous method. In C# 3.0, a delegate could be initialized with a lambda expression, which is more expressive and concise. E.g. in 2.0 the parameter type had to be defined twice (during declaration of delegate and during initialization) and this was done away in 3.0. C++11 has leapfrogged this by removing most redundancies seen in earlier versions of C# and gives a spartan expression of anonymous function definition and invocation. Anonymous functions discussion requires an understanding of the concept of closure. A closure is a function together with a

referencing environment for the non-local variables of the function. Or to quote the ISO/IEC sub-committee technical report [9], “Closure is an anonymous function object that is created automatically by the compiler as a result of evaluating a lambda expression. Closure consists of the code of the body of the lambda function and the environment in which the lambda function is defined”. In practice, this means that external variables referred to in the body are stored (as reference or as copied-value) as member variables of the anonymous function object. Or that a pointer to the frame where the lambda function was created is stored in the function object. The concept of closure was developed in 1960s and featured in Scheme programming. C++11 support closures in two default forms. One stores a copy of the variable, the other stores references to the original variables. Both provide functionality to override this default behaviour for individual variables. A key limitation of the C++11 lambda feature, however, is that C++11 closures are monomorphic. That is, their type does not adapt to the context in which they are called. This is unlike C#.

Now, if we limit ourselves to implementing integral in C, we can use function pointer as shown below. double integrate(double a, double b, double (*ptr2func)(double) ) { int i; double sum =0, dt = (b-a)/N;

// N is number of segments

for( i = 0; i < N; i++ ) sum += ptr2func(a+i*dt) * dt ; return sum; }

The key limitation here is that the pointed-to function ptr2func has to be defined separately from the context in which integrate will be called from. Suppose we need to compute integral of f(x) = u/x+v. We define it as below and then pass a pointer to func_inverse each time we need to integrate f(x) = u/x+v. double func_inverse(double x ) { return u/x+v;

2. Organization of the Paper }

In Sec 3, we provide the advantages of using anonymous function. Sec 4 discusses the formal syntax and semantics of C++11 lambda-expression illustrating key concepts with examples. Sec 5 gets into the details of implementing anonymous function in the front-end and in Open64 [12]. Sec 6 forms the conclusion.

Different contexts from which integrate may be called may have different values of u and v. To overcome this problem, we are forced to set u and v as globals, a highly undesirable solution.

3. Lambda Expression – Motivation

3.2 Integral – Function Object

In this section, we illustrate with examples the advantages of C++11 lambda functions over other forms of expression – such as function pointers of C and object function of C++03.

In C++ prior to C++11, we can use function object or functor to solve the same integral problem in a more elegant manner. A functor is a construct that allows an object to be called as if it were a function. We construct a class (e.g. CFoo) which overloads the function call operator ( ) member function. In C++ this is called class type functor.

3.1 Integral – Function Pointers Consider the problem of writing a function to compute the definite integral [a,b] of a mathematical function f : RR. The basic approach is to divide the area under the curve of f into very narrow rectangles and sum the area of all the rectangles. The integrate function is then actually a higher-order function as it takes not a value but any continuous function as its input.

class CFoo{ public: double u,v; double operator( )(double x){ return u/x+v; } }; double integrate( double a, double b, CFoo f){ int i; double sum =0, dt = (b-a)/N; for( int i = 0 ; i < N; i++ ) sum += f(a+i*dt)*dt;… return sum; } int main( ){ CFoo f_inv_x; f_inv_x.u = … ; f_inv_x.v = …; double a=… b =…; double t = integrate (a, b, f_inv_x); … }

Figure 2 Computing definite integral using functor Figure 1. Computing definite integral by partitioning the area under the curve into rectangles

The code above demonstrates how the idiom of functor is typically used. The functor approach gives efficient local context,

encapsulation and conciseness than function pointer. Instead of setting some global values, we can pass context now by setting the functor‟s member variables. The function pointer points to a function which has simply two contexts – the argument passed to it and the global variables. The functor on the other hand can additionally refer to its own local context or object state (data member) which can be used to generate set of functions using current context. The function object approach has the advantage of context and encapsulation but has much syntactic overhead. The syntactic requirement of defining a class with its member variables, function call operator, and constructor, and then constructing an object of that type is very verbose and thus not well-suited for crating function object “on the fly” to be used only once. The semantics and syntax of lambda expression via translation to function objects, as defined in C++11 is a more concise way of achieving the same and more.

3.3 Integral – Lambda Expression

This increases the readability of the code. If another integral, e.g. x2 has to be computed; only one more line of code is required: double t = integrate (a, b, [u,v ](double x){ return x*x;} );

3.4 Idiomatic uses of C++11 Lambda Expression It is envisioned that lambda-expression in C++11 will help improve brevity of codes in general and be particularly useful for STL based codes. For example, if we want to add up the elements in a vector, we can do it as shown in Figure 4. int sum = 0; for_each( myvector.begin( ), myvector.end( ), [&sum](int i){ sum+=i;});

Figure 4. Using lambda to sum a STL vector

The definition and use of C++11 lambda expression for computing the integral is shown below (Figure 3). template double integrate( double a, double b, F f){ int i; double sum =0, dt = (b-a)/N; for( int i = 0 ; i < N; i++ ) sum += f(a+i*dt)*dt; return sum; } int main( ){ int u=3, v=4 ;

// u and v are local variables

int a = ..., b = … ; double t = integrate (a, b, [u,v ](double x){ return u/x+v;} );

In Figure 4, the variable sum is captured by reference. Therefore when the for_each completes, the summation will be available in sum in the callee. It all looks a bit terse at first but the whole computation is captured in place, which is definitely good for code conciseness and understanding. If we have a record of employees and we are looking for someone with a particular ID, we can do it using STL function find_if and lambda construct as shown in Figure 5: int ID = …; find_if( employeeRec.begin( ), employeeRec.end( ), [=](const employee& e) {return e.ID == ID; });

}

Figure 5. Using lambda with STL find_if function

Figure 3. Computing definite integral using C++11 lambda As this might be the first encounter with C++11 lambdaexpression for some readers, we spend some time here to explain the syntax and its semantics. The square brackets [u,v] indicate the start of a lambda expression. It may or may not be empty. In this case, it captures two local variables u and v by value. Any changes to u and v will not reflect as change in original values. The [.] is followed by (argument-list). The (double x) is actually optional in the case where there are no arguments to the lambda. In this example, there is an argument expected of type double. The last item {…} is the function body. The function definition of integrate has to change to accept the lambda function as a parameter. It must change to template type as shown in Figure 3. Notice that a lot of syntactic verbosity of defining a new class, defining the operator ( ) method, creating an object of that class and copying the variables u and v to it, has been replaced with a single line: double t = integrate (a, b, [u,v ](double x){ return u/x+v;} );

Above, the variable ID is captured by value [=]. Note that the STL definition of find_if is: template InputIterator find_if( InputerIterator first, InputIterator last, Predicate pred) { for( ; first != last; first++ ) if ( pred(*first) ) break; return first; }

The lambda anonymous function becomes an object of a compiler generated internal class with an overloaded operator ( ). Hence it is compatible with the class Predicate as expected by find_if. Our last STL example is of std::sort shown in Figure 6. std::sort( myvector.begin( ), myvector.end( ), MyType& b){ return a < b; });

[ ] (MyType& a,

Figure 6. Using lambda with std::sort

Above is a call to sort function that expects comparison function object that, taking two values of the same type as those contained in the iterator‟s range, and returns true if the first argument goes before the second argument. Having seen three idiomatic STL uses of lambda, we give an example out of STL. Figure 7 show the famous Fibonacci using lambda expressions of C++11: std::function fib = [&fib](int n) -> int {

4. Lambda Syntax and Semantics Here we discuss the syntax and semantics of lambda-expression relying on the C++11 standard specification [1].

4.1 C++11 Specification – Syntax C++11 extends the previous definition of primary-expression with lambda-expression:

if( n <= 2)return 1; else return fib(n-1)+fib(n-2); }

primary--expression:

assert( fib(10) == 55 );

Figure 7. Computing fibonacci using lambda expression

literal | this | (expression) |id-expression | lambda-expression lambda-expression: lambda-introducer lambda-declaratoropt compound-statement

Class template std::function is a general-purpose polymorphic function wrapper type. Instances of std::function can store, copy and invoke any callable target – normal functions or lambda functions or other function objects. We create a function object fib which is of type lambda-expression that takes an int as input and returns an int as output. This is the first time we introduce the trailing-return syntax of C++11 as well. As the reader may have guessed,  int says the lambda returns an int. Note that the implementation of fib uses std::function to create first-class object fib. This fib is then captured and used inside its own lambda-expression to make a recursive call. So in a way, C++11 lambda is not truly anonymous.

3.5 Currying with C++11 Lambda Currying is a technique of transforming a function that takes multiple arguments, to a chain of functions each with a single argument. It was discovered by Moses Schönfinkel and later rediscovered by Haskell Brooks Curry [11]. In theoretical computer science, currying provides a way to study functions with multiple arguments in very simple theoretical models, where functions only take single argument. The example below illustrates how currying can be realized in C++11. In the example in Figure 8, we compute x2+y2 in two steps, each time using a lambda function that accepts only one argument. auto c1 = [ ](int x) { return [x](int y){ return x*x + y*y ;} }; auto c2 = c1(5); //c2 is eq. to [ ](int y){ return 5*5+y*y; } auto c3 = c2(3); //c3 is eq. to value (25+3*3) assert( c3 == (5*5 + 3*3) );

Figure 8. Example of currying using C++11 lambda The lambda object c1 takes an int x argument and returns the function (x2 + y2) where y is a free variable, and x is initialized to whatever value of x it is supplied with. For example, c2 is c1 with x instantiated to 5. In other words, c2 represents specifically the function (25+y2). Note that currying is possible in C++11 as lambda object can return another lambda object.

lambda-introducer: [ lambda-captureopt ]

The lambda-introducer is the indicator that what is to follow must be interpreted as a lambda-expression definition. It can be unambiguously identified by the square bracket [ ] with optional content [lambda-captureopt]. lambda-capture is the list of variables the lambda-expression wants to capture, as part of its closure. Next, lambda-declarator is the function parameter list. Note that the lambda-declarator is optional. If the lambda-expression does not need any argument then we can either put as „( )‟ or just leave it blank. The detailed syntax for lambda-capture is given in Figure 9. From that, we deduce that lambda-capture could be [ ], [=], [&], [id], [&id], [&,id1, id2], [=,id1,this,&id2] amongst others. Not all though will be semantically acceptable. lambda-capture: capture-default | capture-list | capture-default, capture-list capture-default : & | = capture-list: capture | capture-list , capture capture: identifier | & identifier | this

lambda-declarator: (parameter-declaration-clause) attribute-specifieroptmutableopt exception-specificationopttrailing-return-typeopt

Figure 9 The lambda-declarator is the argument list with an option trailing type, e.g. int signifies that the return type is int. The compound statement is simply the lambda function body and is a sequence of zero or more statements within { }.

4.2 C++11 Specification – Semantics

5. Lambda Expression – Implementation

The lambda-expression can refer to variables declared outside its body. Table 1 below clarifies the two modes of capturing externally defined variables – by reference or by value.

Here we explain the conversion of lambda expression to compiler‟s intermediate (e.g. WHIRL) format [12].

5.1 Parsing Lambda Expression []

The lambda-expression cannot access any external variables in its body. e.g. [ ]( int i){ return i+j; } //error as j is external and not captured

[& ]

Table 2 shows some of the information gathered in GCC frontend1 during the parsing of lambda-expression declaration [10].

Any external variable is implicitly captured by reference if it is used in the lambda function.

INFORMATION

DESCRIPTION

LAMBDA_EXPR

Tree code for lambda-expression

LAMBDA_EXPR_DE FAULT_CAPTURE

enum {NONE /*[ ]*/, BY_VALUE /*[=]*/, BY_REFERENCE /*[&]*/ }

e.g. [=]( int i){ j++; return i+j; } //j is locally incremented

LAMBD_EXPR_CAPT URE_LIST

Each item is stored as a structure

Any external variable is implicitly captured by reference, other than j which is captured by value.

LAMBDA_EXPR_RE TURN_TYPE_MODE

enum { NONE, SUPPLIED /*->*/}. When not supplied, lambda body ‘return …’ indicates the return type.

LAMBDA_EXPR_RE TURN_TYPE

Either supplied or computed from the lambda body later.

LAMBDA_EXPR_MU TABLE

enum {YES, NO} //state can change after creation

LAMBDA_EXPR_THI S_CAPTURED

enum {YES, NO}

e.g. [&]( int i){ j++; return i+j; } //changes made to j is reflected upon return [=]

[&,j]

Any external variable is implicitly captured by value if it is used in the lambda function.

e.g. [&,j]( int i){ j++; k++; return i+j+k; } //j is locally incremented. k increment changes external value [=,j]

Any external variable is implicitly captured by value, other than j which is captured by reference. e.g. [ ]( int i){ j++; k++; return i+j+k; }

[this]

Special case. Refers to enclosing class this pointer

[&,&j]

Error. j is already captured by reference by default

[=,this]

Error. this when =, this is captured by default

[i,i]

Error. i repeated.

[&this]

Error. Cannot take address of this

[42]

Error. Expects identifier or & or = or this

Table 1. Lambda capture modes C++11 extends the definition of keyword auto to accommodate lambda expression. The auto type-specifier signifies that the type of a variable or reference being declared shall be deduced from its initializer or that a function declarator shall include a trailingreturn-type. We give some examples more below of lambda-expression formulation with implied semantic interpretation. [ ]{ }( );

//valid lambda-function which does nothing

A lambda object can be captured by another lambda object as the gcd implementation shows below: auto rem = [ ]( int x, int y) { return x%y; };

Table 2. Information gathered during parsing of lambda The beginning of lambda-expression is triggered by recognition of token „[„. If this is followed by „&‟ and „&‟ is not followed by any identifier then the default capture is by reference. If „[„ is followed by „=‟ then default capture is by value. The capture-list, if you note in the grammar specification, is either id, &id or this. If default capture is „&‟ by reference, then appearance of „&id‟ is an error as it is already captured by default. If a lambda-capture includes a capture-default that is „=‟, the lambda capture shall not contain this and each identifier must be preceded by „&‟.

5.2 Semantic Analysis of Lambda Expression The evaluation of a lambda-expression results in a prvalue (pure rvalue) temporary. This temporary is the closure object. A closure object behaves like a function object. The type of a lambda-expression is (which is also the type of the closure object) is a unique, unnamed non-union class type- called the closure type. This class type is not an aggregate. The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the lambda expression.

std::function gcd = [&gcd, &rem ] (int x, int y) { if (y==0) return x; else return gcd(y, rem(x,y); }; assert(gcd(21,49) == 7);

1

Footnotes: GCC 4.5 supports lambda-expressions in experimental form. Current Open64 uses GCC 4.2 as front-end which does not have support for C++11 features.

The closure type for a lambda expression has a public inline function call operator whose parameters and return type are described by the parameter-declaration clause and trailing returntype. Any exception specification applies only to the corresponding function operator. If the lambda-expression does not include a trailing return-type it is as if the trailing return-type denotes the following type: 

well but does not in this case. The lambda then uses this to access data member i. The first thing we show is the equivalent conversion of the lambda internally by the front-end to a struct with an overloaded function call operator. The names of internal types and variables are chosen to be expressive of their role. Figure 12 shows the resulting changes to function body of get.

If the compound-statement is of the form { return attribute-specifieroptexpression; } Then the type of the return is the expression after lvalue-to-rvalue conversion and function-to-pointer conversion.



otherwise, void.

It is important to note that the initialization of captured values occurs at the time of lambda object creation and not when the lambda function is invoked. class test{ public: void print( std::function f){ std::cout << f( ) << endl; } }; int main( ) { int i = 4; std::function foo =[ i ]( ){ return i*i; }//the lambda test t; i=5; t.print( foo ); //value printed is 16 and not 25. }

Figure 10. Closure creation at time of lambda definition For the example in figure 10, even though „i=5‟ occurs before the call to „foo( )‟, the value printed is still 16. If the capture was by reference [&i] then value printed would be 25.

class T{ public: int i; …. get( ) { struct Lambda1{ public: T* enclosureThisPointer; //closure int operator( )( ){ return enclosureThisPointer->i; } }lam; lam.enclosureThisPointer = this; //copy this of T to closure return lam( ); //call lambda }//get( ) };

Figure 12. Lambda converted to struct with overloaded function call operator Notice that a new structure Lamda1 is defined. It has data member of type T* to capture this of T. Also it defines a function operator ( ). Next, this of T is copied to enclosureThisPointer. Finally, lam.operator( ) is invoked which is the act of calling the lambda expression. In general, lambda or otherwise, classes are implemented as structures with associated member-methods. The first parameter of any object.method invocation is the „this’ pointer, which provides access to the state (variables in the object). Figure 13 shows this translation. We show this as it will help understand the final WHIRL with more ease.

5.3 Translating Lambda Expression We now explain the translation of lambda expressions by the front-end of the compiler to a form that can be integrated into existing, i.e. pre C++11, compiler infrastructure and its intermediate representation, or IR, such as WHIRL. Consider the example in Figure 11. class T { public: int i; void set(int v) { this->i = v; } int get( ) { return [this]( ) {return this->i;}( ); } }; int main( ) { T t; t.set(5); assert( t.get( ) == 5); return 1; }

Figure 11. Lambda example capturing this of its enclosure In this example, there is a lambda expression in method get. The lambda captures this pointer, which is the pointer to the enclosing object of type T. It could have captured individual members as

int _ZN1T3getEv( struct T *const this){ struct Lamdbda1 lam; //create  closure lam.enclosureThisPointer= this; //prepare closure return _ZZN1T3getEvEN7Lambda1clEv(&lam); //call  } int _ZZN1T3getEvEN7Lambda1clEv(Lambda1 *const closure) { return constclosure->enclosureThisPointer->i; } int main( ) { T t; _ZN1T3setEi (&t, 5); assert(_ZN1T3getEv(&t) == 5 ); return 1; }

Figure 13. Conversion of method to a normal function with this pointer as an argument There are a couple of points to note carefully about the conversion by the front-end. Firstly, note that the function _ZN1T3getEv, i.e. T::get, is passed a pointer to structure of type T which is the „this’ pointer of object t. This mechanism exists today already in

WHIRL. _ZN1T3getEv declares and initializes the struct Lambda1. This structure contains the values and references that were captured by the lambda-expression definition. As thispointer of T was specified as a capture item, Lambda1 has an element enclosureThisPointer. Function _ZZN1T3getEvEN7Lambda1clEv receives a pointer to Lambda1 structure. We call it closure although technically closure includes the function itself. The closure contains reference and values of all captured variables. In _Z1T3get7lambda1clEv, it is then used to gain access to variable i. It is important to note that the initialization of captured values occurs at the time of lambda object creation and not when the lambda function is invoked. Figure 14 shows the WHIRL for the method get. At line 6-7, we note the copying of this pointer to lam.enclosureThisPointer. In lines 9-11, the Lambda1 *lam is passed as parameter to lambda call _ZZN1T3getEvEN7Lambda1clEv. 1. FUNC_ENTRY <1,53,_ZN1T3getEv> 2. IDNAME 0 <2,4,this> 3. BODY 4. BLOCK {line: 1/8} 5. PRAGMA 0 119 0 (0x0) # PREAMBLE_END 6. U8U8LDID 0 <2,4,this> T<56,anon_ptr.,8,C> 7. U8STID 0 <2,5,lam> T<69,Lambda1,8> 8. BLOCK {line: 0/0} 9. U8LDA 0 <2,5,lam> T<71,anon_ptr.,8> 10. U8PARM 2 T<71,anon_ptr.,8> # by_value 11. I4CALL 126 <1,57,_ZZN1T3getEvEN7Lambda1clEv> 12. END_BLOCK 13. I4I4LDID -1 <1,49,.preg_return_val> T<4,.predef_I4,4> 14. I4COMMA 15. I4RETURN_VAL 16. END_BLOCK

Figure 14. WHIRL of get which encloses a lambda call

efficiency-minded that programmers may capture „this‟. So the copy propagation has to just optimize „this‟ copy.

6. CONCLUSION We presented a bit of the general philosophy of lambda expression and some motivation of why programmers may be excited to start using this new C++11 language feature. Also, we showed some idiomatic uses of lambda expressions. We covered the syntax and semantics using the C++11 standard as reference. Then we covered how lambda may be translated by the front-end of the compiler to a representation that is compatible with existing intermediate-level representation in the compiler such as WHIRL. We note that the WHIRL may not be severely impacted. We concluded, however, that generating efficient code for lambda expressions may be the real challenge behind its use.

7. REFERENCES [1] C++11 N3242. Working Draft, Standard for Programming Language C++. http://www.openstd.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf. [2] Alonzo Church, 1932. A Set of postulates for the foundation of logic. Annals of Mathematics Series 2, 33:346-366. http://profs.info.uaic.ro/~fltiplea/CDC/Chur1932.pdf [3] Barendregt, H. P. The Lambda Calculus: Its Syntax and Semantics. Elsevier Series. [4] Greg Michaelson. An Introduction to Functional Programming through Lambda Calculus. Dover Books on Mathematics. [5] Jan van Eijck and Christina Unger. Computational Semantics with Functional Programming. Cambridge University Press.

Figure 15 shows the WHIRL for the lambda function itself. Note that pointer variable „this‟ corresponds to „const closure’ used in figure 13. 1. FUNC_ENTRY <1,57,_ZZN1T3getEvEN7Lambda1clEv> 2. IDNAME 0 <2,4,this> 3. BODY 4. BLOCK 5. U8U8LDID 0 <2,4, this> T<71,anon_ptr.,8> 6. U8U8ILOADT<69,Lambda1,8> T<71,anon_ptr.,8> 7. I4I4ILOAD 0 T<55,T,4> T<56,anon_ptr.,8> 8. I4RETURN_VAL 9. END_BLOCK

Figure 15. WHIRL of a lambda function

5.4 Lambda Overhead & Optimization Lambda expression does not incur additionally overhead as such compared to the function object creation method employed generally in C++03. Inlining will be key to an efficient implementation especially, as envisioned, large parts of lambda expression usage will be for small function. Additionally, efficient copy propagation should remove redundant copies made for the closure during lambda to function-object creation. It is likely that when several members of the enclosing object are referenced,

[6] Andrew Troelsen, Pro C# and the .NET Platform. ISBN 978-1-4302-2549-2. [7] Richard Bird. Pearls of Functional Algorithm Design. Cambridge University Press. Cambridge 2010. [8] C. A. Hoare and Richard Bird. Introduction to Functional Programming using Haskell. Prentice Hall Series in Computer Science. University of Oxford. 1988. [9] Jaako Jarvik, John Freeman, Lawrence Crowl. Lambda expressions and Closures. Technical Report. Information technology sub-committee SC 22, WG-21, Programming Language C++. http://www.openstd.org/jtc1/sc22/wg21/docs/papers/2008/n2550.pdf [10] GCC Patch to merge lambda branch. http://gcc.gnu.org/ml/gcc-patches/2009-09/msg02165.html [11] Strachey, Christopher. Fundamental Concepts in Programming Languages. 2000. [12] Open64 Manuals. www.open64.net. http://sourceforge.net/projects/open64/files/open64/Docume ntation/ [13] Anonymous Functions (C# Programming Guide). http://msdn.microsoft.com/en-us/library/bb882516.aspx

Proceedings Template - WORD

entity that has no restriction on its use. First-class ... entities such as numbers can appear, including as arguments to ... In C# 2.0, a delegate could be initialized with inline code, called anonymous method. In C# 3.0, a delegate could be initialized with a lambda expression, which is more expressive and concise. E.g. in 2.0 ...

879KB Sizes 3 Downloads 321 Views

Recommend Documents

Proceedings Template - WORD
This paper presents a System for Early Analysis of SoCs (SEAS) .... converted to a SystemC program which has constructor calls for ... cores contain more critical connections, such as high-speed IOs, ... At this early stage, the typical way to.

Proceedings Template - WORD - PDFKUL.COM
multimedia authoring system dedicated to end-users aims at facilitating multimedia documents creation. ... LimSee3 [7] is a generic tool (or platform) for editing multimedia documents and as such it provides several .... produced with an XSLT transfo

Proceedings Template - WORD
Through the use of crowdsourcing services like. Amazon's Mechanical ...... improving data quality and data mining using multiple, noisy labelers. In KDD 2008.

Proceedings Template - WORD
software such as Adobe Flash Creative Suite 3, SwiSH, ... after a course, to create a fully synchronized multimedia ... of on-line viewable course presentations.

Proceedings Template - WORD
We propose to address the problem of encouraging ... Topic: A friend of yours insists that you must only buy and .... Information Seeking Behavior on the Web.

Proceedings Template - WORD
10, 11]. Dialogic instruction involves fewer teacher questions and ... achievment [1, 3, 10]. ..... system) 2.0: A Windows laptop computer system for the in-.

Proceedings Template - WORD
Universal Hash Function has over other classes of Hash function. ..... O PG. O nPG. O MG. M. +. +. +. = +. 4. CONCLUSIONS. As stated by the results in the ... 1023–1030,. [4] Mitchell, M. An Introduction to Genetic Algorithms. MIT. Press, 2005.

Proceedings Template - WORD
As any heuristic implicitly sequences the input when it reads data, the presentation captures ... Pushing this idea further, a heuristic h is a mapping from one.

Proceedings Template - WORD
Experimental results on the datasets of TREC web track, OSHUMED, and a commercial web search ..... TREC data, since OHSUMED is a text document collection without hyperlink. ..... Knowledge Discovery and Data Mining (KDD), ACM.

Proceedings Template - WORD
685 Education Sciences. Madison WI, 53706-1475 [email protected] ... student engagement [11] and improve student achievement [24]. However, the quality of implementation of dialogic ..... for Knowledge Analysis (WEKA) [9] an open source data min

Proceedings Template - WORD
presented an image of a historical document and are asked to transcribe selected fields thereof. FSI has over 100,000 volunteer annotators and a large associated infrastructure of personnel and hardware for managing the crowd sourcing. FSI annotators

Proceedings Template - WORD
has existed for over a century and is routinely used in business and academia .... Administration ..... specifics of the data sources are outline in Appendix A. This.

Proceedings Template - WORD
the technical system, the users, their tasks and organizational con- ..... HTML editor employee. HTML file. Figure 2: Simple example of the SeeMe notation. 352 ...

Proceedings Template - WORD
Dept. of Computer Science. University of Vermont. Burlington, VT 05405. 802-656-9116 [email protected]. Margaret J. Eppstein. Dept. of Computer Science. University of Vermont. Burlington, VT 05405. 802-656-1918. [email protected]. ABSTRACT. T

Proceedings Template - WORD
Mar 25, 2011 - RFID. 10 IDOC with cryptic names & XSDs with long names. CRM. 8. IDOC & XSDs with long ... partners to the Joint Automotive Industry standard. The correct .... Informationsintegration in Service-Architekturen. [16] Rahm, E.

Proceedings Template - WORD
Jun 18, 2012 - such as social networks, micro-blogs, protein-protein interactions, and the .... the level-synchronized BFS are explained in [2][3]. Algorithm I: ...

Proceedings Template - WORD
information beyond their own contacts such as business services. We propose tagging contacts and sharing the tags with one's social network as a solution to ...

Proceedings Template - WORD
accounting for the gap. There was no ... source computer vision software library, was used to isolate the red balloon from the ..... D'Mello, S. et al. 2016. Attending to Attention: Detecting and Combating Mind Wandering during Computerized.

Proceedings Template - WORD
fitness function based on the ReliefF data mining algorithm. Preliminary results from ... the approach to larger data sets and to lower heritabilities. Categories and ...

Proceedings Template - WORD
non-Linux user with Opera non-Linux user with FireFox. Linux user ... The click chain model is introduced by F. Guo et al.[15]. It differs from the original cascade ...

Proceedings Template - WORD
temporal resolution between satellite sensor data, the need to establish ... Algorithms, Design. Keywords ..... cyclone events to analyze and visualize. On the ...

Proceedings Template - WORD
Many software projects use dezvelopment support systems such as bug tracking ... hosting service such as sourceforge.net that can be used at no fee. In case of ...

Proceedings Template - WORD
access speed(for the time being), small screen, and personal holding. ... that implement the WAP specification, like mobile phones. It is simpler and more widely ...

Proceedings Template - WORD
effectiveness of the VSE compare to Google is evaluated. The VSE ... provider. Hence, the VSE is a visualized layer built on top of Google as a search interface with which the user interacts .... Lexical Operators to Improve Internet Searches.