Friday, 30 May 2008

God wrote in LISP: programming and genesis.

Did you ever ask yourself what programming language God used to implement the Universe? I mean, he had a pretty tight deadline - only 6 days - so he must have been using something rather high level. And a rather complex one to boot. And as a programmer, you don't have any doubts thet God must have been using a programming language for the task: without abstraction the task is just too complex ;-).

I came across this song while hearing the OOPSLA podcasts and everything became clear: he used LISP! Hear it here: ( >> )*. I must say, I really like it a lot. It's wonderful: it's like a hymn on a great, dead language. The lyrics come from Bob Kanefsky. All I could trace about him is that he wrote some parody songs, but he must be a programmer himself judging from the quality of lyrics.

And the lyrics are right: Object Oriented languages describe how we humans are thinking about the world, but LISP (or functional languages in general) describe the thoughts of God... so pure... ;-). Let me cite: "Don’t search the disk drive for man.c...". It's almost ontology, I like it :-).

PS: As always there is a monority opinion as well, see http://www.xkcd.com/224.

---
* or here, if embedding works:

.

Thursday, 15 May 2008

Why is software engineering not engineering?

As I had a look over Philippe Kruchten's book "The Rational Unified Process. An Introduction" I noticed the following passage. I mean, the book is rather dry, it just describes some organizational process, but this paragraph was different:

"Software engineering has not reached the level of other engineering discipline .... because the underlying "theories" are week and poorly understood and the heuristics are crude."
Well, nothing new here, just like we all know it to be. Then:

"Software engineering may be misnamed. At various times it more closely resembles a branch of psychology, philosophy or art than engineering. Relatively straightforward laws of physics underlie the design of a bridge, but there's no strict equivalent in software design. Software is "soft" in this respect."
Indeed! In programming we are not working with physical materials but with mental objects (or should I say artifacts?) denoted by an array of characters on a sheet of paper. Sometimes even with just boxes and lines*. So what we really are doing, when we're trying to set up some laws in software, is looking for the "laws of thought", i.e. we are trying to find a good way to organize our ideas! Ideas which will then become flesh when executed on a complicated machine. As we are working with mental objects to a much greater extend than traditional engineering, the methodology cannot be the same. The world of human thought is not so well explored as the physical world. Or maybe the physical world is just much, much simpler?

This discussion would lead us too far**, but one thing is sure: on some level of abstraction, we are no more thinking about the underlying machine, a thing which couldn't happen when we were designing a bridge. Because of that I maintain that in programming we are basicaly working with mental and not physical objects, so it cannot be counted as engineering. That might be the case earlier on, as programmers had all the iron on their hands, setting plugs and connecting cables. It had an engineering-like looks. But today? Just look on an corporate IT department - it's all about organisation, processes, abstractions of every level. For me it has more to do with "management science" and even "social science", only on a different scale.

So it should be best called computer "science" - not in the "scientific" sense, but rather in the "soft-science" sense? This would however mean, that it is somehow an art... Well, it's not what the industry wants to hear! But we don't have to tell them ;-).

---
* MDD (or should I call it MDA?) takes it to the extreme: you don't write ANY code at all, instead you are writing the "computation independent model", of course in UML, which constitutes a description of the functionality of the system. Then you are transforming this model into another model: "platform independent model", which represents the abstract computation model, then you are tranforming this into a "platform specific model" at last. And all of this is done using tools, profiles, configurations, cartriges. Ideally, you should only model the required functionality, choose the target platform, and start the model transformation chain. Cool! But is it still programming? Theoreticall it is.

** i.e. into philosophy. Just consider that civil engineers are working with mental models too, and, on the other side, the matematicians are working with "mental objects", which miraculously can describe the physical worlds with a great precision...

Sunday, 27 April 2008

pocket C++ lambda library, part IIa


Are you wondering about the title of this entry? Well, it really should by part of a previous one*, but after looking at it I decided that the previous entry is pretty long already, and I wasn't willing to blow it up even more. And the theme isn't such an interesting one as to deserve a separate part in this mini-series. What is it we are talking about?

1. Access to the members


In the past I sometimes really wanted to be able to do the following:

    struct XXX { int value; int getValue() { return value; } };
    vecx<XXX*> vec_x;
    find_if(vec_x.begin(), vec_x.end(),  _$1->value == alive);
i.e. to access the members of an object out of the lambda function. Of course I'd like a code like _$1.value the best, but C++ doesn't allow us to overload the dot operator! Why not? This would mean that we could customize the method invocation mechanism itself! As it's the case in Groovy, Perl, Python or even Java**:

// Groovy:
Object invokeMethod(String name, Object args)
{
    log("Just calling me: $name");
    def result = metaClass.invokeMethod(this, name, args);
}
If you have that, you can do things like Rails in Ruby and builders in Groovy. You just intercept calls to the nonexisting methods (i.e. overload the methodMissing()/method_missing() in Groovy/Ruby or __getattr__() in Python) and install the "code block" (a closure, as to be exact) passed as one of the parameters in a custom hash map with the name parameter as key... You've got the message.

This isn't possible in C++, as it would introduce the metaclass notion into the language. At least it would require a common superclass for all C++ objects, and this contradicts the design of C++ classes (AFAIK) as thin wrappers for physical memory segments. On the other side, C++ has a more primitive notion of call intercepting: overloading of the -> operator! Alas, it only works with pointers, so we cannot provide a general solution for value based containers. An that is a bad thing enough.

So let's concentrate on the less ambitious goal: _$1->getValue()! Unfortunately, even this syntax canot be made work in our context! Why? Because for the C++ compiler the expression getValue() doesn't make sense! It doesn't refer to a class' method getValue(), which we could feed to the -> operator, it's just a string which we'd like to transform somehow in a function reference!

So what can we do (if anything)?

2. The Implementation


The best I could produce is the following:
    iterx = find_if(vecx.begin(), vecx.end(), _$1->*(&XXX::value) == 2);
    iterx = find_if(vecx.begin(), vecx.end(), _$1->*(&XXX::getValue) == 1);
Well, what can I say, it's passable. Now the compiler has a meaningful information in form of a member address, and it's not too ugly. How to implement it? With a standard technique from the first part***:
    // ->*
    template<class V, class O> struct ArrowStar : public lambda_expr {
        V O::* mptr;
        ArrowStar(V O::*m): mptr(m) { }
        V operator()(O* o) const { return o->*mptr; }
    };
we are overloading the member call operator for memebr access. For function member calls we need 2 more overloads. First for calls with 1 argument:
    template<class R, class O, class A> struct ArrowStarF : public lambda_expr {
        R(O::*fptr)(A);
        ArrowStarF(R(O::*f)(A)): fptr(f) { }
        R operator()(O* o, A a) const { return o->*fptr(a); }
    };
and for calls without arguments:
    template<class R, class O> struct ArrowStarFv : public lambda_expr {
        R(O::*fptr)();
        ArrowStarFv(R(O::*f)()): fptr(f) { }
        R operator()(O* o) const { return (o->*fptr)(); }
    }
nothing new here as well, just the standard operator overloading technique. For the == operation to work, I extended the EqTo operator from the part 1*** to do a little forwarding. I know, I should use the forwarders (like Le2_forw in part 1), but I was lazy:
    // lambda_expr ==
    template<class S, class T> struct EqTo : public lambda_expr {
        ...
        EqTo(S s, T t) : lexpr(s), val(t) { }
        template <class R>
            bool operator()(R r) { return lexpr(r) == val; }
    };
So let's do something useful at last:
    // shouldn't clash with lambda_expr: *_$1 <= *$2 !!!
    iterx = find_if(vecx.begin(), vecx.end(), _$1->*(&XXX::getVal) <= 2);
    // read field values from vecx
    vector<int> v10_1(10);
    transform(vecx.begin(), vecx.end(), v10_1.begin(), _$1->*(&XXX::getVal));
    // assign to a external counter
    int aaa;
    for_each(vecx.begin(), vecx.end(), aaa += _$1->*(&XXX::value));
Ok, the last one won't be working just now ;-), you must wait for the part 3 of the series! For the first one to work, we must extend the forwarding class from part 1*** a little for the case where only one side must be forwarded:
    template <class S, class T> struct Le2_forw : public lambda_expr
    {
        S e1;
        T e2;
        Le2_forw(S s, T t) : e1(s), e2(t) { }
        .....
        template <class U> // one side is bound! OPEN: assume left side!
            bool operator()(U a) const { return e1(a) <= e2; }
    };
And now everything is buzzing!

3. Discussion


If you think the sytax of the meber function call ist just horrible, there is another possibility to use the member functions: bind them! This you have seen (and frowned upon) in part 2*:
    for_each(vecx.begin(), vecx.end(), cout << bind(&XXX::getVal, _$1));
it's even less readable, is it? Or maybe not? Look, compared with _$1->*(&XXX::value) it's no more SUCH a bad sight! Maybe something like call_func(_$1, &XXX::getVal) would be more readable here? The advantage of this solution is that we could accept value objects in the container, and take it's address internally. I leave the decision to you, the implementation is more or less trivial.

Summing up, I couldn't achieve much progress here, because of inherent C++ design features. So maybe a macro solution? Or another level of indirection? What we really needed here is a hook for compiler errors (method not found), where we could install our own code snippet. Wait a minute! Something like compile time asserts? But how can I get around the string => function coding problem?

Something primitive like this would be possible:
    ...
    ArrowStarStr(string& name): fname(name) { }
    R operator()(O* o) const {
        return (o->func_hashtable.get(name))(); // and don't crash here!
    }
But you cannot use a POCppO anymore, you need some macro gadgetry like in Qt,
for example:
    struct XXX {
        int value;
        int getValue() { return value; }

        // now decorate:
        STORE_LAMDBA_FUNC(getValue);
    };
    // or property based:
    struct XXX {
        DEF_LAMBDA_PROPERTY(value, int);
    };
Not so pretty, not elegant, much to much effort needed. But it is the solution we have to use following the C++ language design. We just don't have introspection and cannot overload the dot. Sorry. Any ideas?

--
* http://ib-krajewski.blogspot.com/2008/01/c-pocket-lambda-library-part-2.html
** with dynamic proxies: see http://gleichmann.wordpress.com/2007/11/22/mimicry-in-action-dynamically-implement-an-interface-using-dynamic-proxy/
***http://ib-krajewski.blogspot.com/2007/12/c-pocket-lambda-library.html

Sunday, 6 April 2008

Language trends and waiting blues.

Hi everbody! I recently skimmed over an interview* about programming language trends in the DDJ. In general, there was nothing new in there, rather a re-statement of the widely known programming trends. But some phrases caught my eye nonetheless:

PJ: C and C++ are definitely losing ground. There is a simple explanation for this. Languages without automated garbage collection are getting out of fashion.
....
Another language that has had its day is Perl. It was once the standard language for every system administrator and build manager, but now everyone has been waiting on a new major release for more than seven years. That is considered far too long.
As I'm mainly a C++ programmer in my bussines life, the news of the proceeding C++'s demise worry me, if only it acknowledges what I see with my own eyes. So this fact alone is not what I want to talk about, but rather about C++ similarity to Perl. Why?

Look, can't you see a parallel to the Perl's fate here? I cite: "everyone has been waiting on a new major release for more than seven years". And there's still no Perl 6! Recall, there were plans for Parrot**, a common VM for Perl and Python (or was it just a joke?). Everyone was excited, but nope, Python won't use Parrot, Parrot is only in its 0.x versions**, so Perl 6 won't come soon, and the situation generally is a mess.

Isn't that somehow similiar to the situation of C++? The last standard (or rather a correction of it) dates back to 1998, i.e. 10 years ago! It's even longer than Perl. So maybe C++'s retreat is due to lack of new language standard like in Perl's case? When I look at Java, I must admit I envy it. Just recall the evolution: while Java 4 was still rather a primitive language without much interesting features (sorry, perhaps with exception of proxies and introspection), already Java 5 brought foreach, generics, annotations, lock-free synchronisation, lock-free data structures, autoboxing and a new the memory model. Admittedly Java 6 wasn't that iteresting language-wise but Java 7 will get things like closures or fork-join support for easy multicore parallelism***! This gets you a wholly new, interesting language.

Contrast that with years-long discussion about what is to be included in the C++0x standard. And I still don't know what exactly is to come! Will a new memory model be included? And lambda functions? Garbage collection? Sometimes we all think that the new Standard won't be named C++0x, because years and years of discussion will be still needed!

So maybe the quote of Bjarne Stroustrup****:
"Java shows that a (partial) break from the past—supported by massive corporate backing — can produce something new. C++ shows that a deliberately evolutionary approach can produce something new — even without significant corporate support."
is false? Mabe only a corporate-backed language has a chance today? Look how quickly Java developed and how the new C++ standard stalls. But maybe it's the "design by committe"-effect on the side of C++? I don't know.

--
* Programming Languages: Everyone Has a Favorite One: ttp://www.ddj.com/cpp/207401593
** Parrot Virtual Machine: http://www.parrotcode.org/
*** Java theory and practice: Stick a fork in it, Part 1: ttp://www.ibm.com/developerworks/java/library/j-jtp11137.html
**** his interview of 2006: http://technologyreview.com/Infotech/17868/page3/

Sunday, 30 March 2008

QString conversions, bugs, suprises and design

1. A trivial bug


It started with a pretty simple piece of code:
    QDomElement e = n.toElement(); // try to convert the node to an element.

if(!e.isNull())
{
TRACE(e.tagName());
....
where TRACE() sends an object to cout. The simplest of tasks you'd say, but it didn't compile. What? What year is it now? Are we in the early nineties? Doesn't library writers know about the standard library? It turned out, they know, so I used a slightly modified code:
    TRACE(e.tagName().toStdString());
but it always crashed with Qt 4.3, Windows XP and VisualStudio 2005! Why? No time to check. After some reading of Qt docs, I settled with:
    TRACE(e.tagName().toAscii().data());
It worked, but the code looked extremely ugly! After copy-pasting it for n times (no, n wasn't equal to 3, as it should be according to the Agile gospel, sorry!!!) I longed for something more elegant and explicit, something like:
    TRACE(qstr_cast<const char*>(e.tagName()))
The code was quickly written and worked instantly:
    // helper for QString conversions
// -- cute and explicit syntax: qstr_cast<const char*>()!


template <class T>
inline T qstr_cast(const QString& s)
{
return T(s.toAscii().data());
}

inline const char* qstr_cast(const QString& s)
{
return s.toAscii().data();
}
Well, it worked on my machine but not in the target environment, and only in one (different) case. Why? Of course I blamed the Qt runtime support, which already let me down with the toStdString() function. Then I saw the same effect in the debugger on my developemnt machine, and I blamed it on multithreading: there must be something wrong with locking when accessing this particular QString instance. But at last I found time to remove this bug, and looked at the sychronisation, and it was 100% correct. The bug was hidden elsewhere. The new (correct) code is:
    // helper for QString conversions
// -- cute and explicit syntax: qstr_cast<const char*>()!


template <class T>
inline QByteArray qstr_cast(const QString& s, T* t = 0)
{
// the QByteArray's const char* conversion op. will be applied
// by the compiler in the const char* context!

return s.toAscii();
}
As you can see, the old code returned a pointer to the data of a temporary instance of an QByteArray object, and of course it pointed into the void. End of story!

2. Discussion of the trivial bug


Why am I writing this? Isn't it just a banal and stupid bug? I don't think so. I think there are some points to be made.

The first one is that Qt doesn't follow the "Principle of Least Surprise"*. This code should work out of the box: cout << qtStringObj;! Why? Because C++ programmers wrote code like this for centuries! Well, almost. In the "freedom languages" ;-)** you are accustomed to writing just: print someObj; and it always works. Mind I didn't use the word "modern languages" but in modern times we expect it just to be working!

The second one is that Qt doesn't want me to use the standard library! There is no shift operator for std::ostream instead they want me to use their QStream class, which I don't know and have no desire to learn. As for QString class the Qt partisans maintain that it is vastly superior to the std::string class, but what about cout? It is somehow an C++ keyword by now. And besides, why aren't I allowed to make my own choices, even if I choose to use an inferior alternative? Maybe I don't have to be that fast in my prototype implementation? You somehow feel trapped in the proprietary Qt world, and somehow cast back in time. Is that the backwards compatibility with the original 80-ties or 90-ties design? It feels somehow frumpy.

The third one is that once I decided on the syntactic appearance of the function (i.e. qstr_cast<>() and not for example cstr_ptr() or CSTR()), I subconsciously settled on a implementation: just get the internal string data and export the pointer to the char buffer. Alas, in case of the QString this doesn't work that way! Moreover, it's not only the name choice alone, this code would work with all the string classes I knew in my long C++ life. So maybe I chose the name because subconsciously I already knew how to implement it? We pride ourself on being rational beings, but we don't know how much we depend on subconscious shortcuts, which will normally work in a familiar territory, but fail when trying something new. Just like me, as I'm relatively new to Qt.

And what's the moral? It's elementary dear Watson: RTFM first! Or perhaps: don't mix Qt and STL???

---
* for example "Applying the Rule of Least Surprise" from "The Art of Unix Programming" by E.S. Raymond: http://www.faqs.org/docs/artu/ch11s01.html or "Principle of Least Astonishment" at Portland Pattern Repository: http://c2.com/cgi/wiki?PrincipleOfLeastAstonishment

** I thought it was a joke, but not, it's an essay by Kevin Barnes: http://codecraft.info/index.php/archives/20/


Tuesday, 26 February 2008

Rentree plus Some Comments on Google-Solvers & Co

Hi everybody! I'm back from my travels and can write some more blog-gobbledegook again (which I'll gladly do). I was away for some serious off-piste skiing in St.Anton, descending some pretty steep, big faces, and taking my first pinwheel tumble on a 40 degrees, Alaska-like, highly exposed, rock-fringed slope. Whow! And then I was back in town, and procuring my next project in just 2 days, taking a head-first plunge here as well ;-).

So let me start my rentree into the blogosphere with something less exciting, i.e. some comments on my previous posts. In fact, I wanted to comment on the Google-Solvers post for quite a long time, so it suits me fine.

Commenting on Java vs. C++


As some of you maybe remember, in a previous post* I compared the perfomance of Python, Perl, Java and C++ (admittedly in a rather ad-hoc manner), and made at first the error of not using the optimization switch of my C++ compiler. Me, a die-hard C++ hacker!!! This resulted in Java and C++ being on par performance-wise. So you can imagine my amazement some time ago when I saw in Uncle Bob's blog these statements**:

You can blame this on the non-optimized gcc compiler I was using (cygwin) but again: Oh boo hoo!. If there are any C++ programmers out there who smirk at the supposed slowness of Java, I think you'd better reconsider.
...
I'll grant you that the JVM can be large. However, if you assume it's already there, then the size of the bytecodes for the application itself need not be very large at all. And the heap can be constrained to a relatively small size to prevent virtual memory thrashing. So, if _engineered_ a java app should give a C++ app a run for it's money in most cases. -UB

Well, this started me thinkig. When you are looking for information concerning Java performance, you can see some typical quotes like this on the web ***:

John Davies: It is just the main reason why there are still diehards that stick with C/C++ because you can guarantee performance, not necessarily faster, but it just guarantees the performance and we will run something in Java, it will run quite frequently faster on C [he means JVM] than it would have done in C/C++, but every now and then it will just pause and that pause can be extremely expensive.
If you'll allow a small comment (hypothesis?, heresy?) from yours truly: what if all those measurements are done without the -O2 switch? It's an all to easy trap to fall into (see my own sufferings*) and an excellent opportunity for the marketing people to use some techniques from the seminal book "How to Lie with Statistics" ;-). Becuse you really can't explain to me that a language which is: 1. interpreted, 2. relies heavily on dynamic memory allocation, and 3. supports garbage collection, can be faster than one which doesn't do it, no matter how much optimization you throw at it! Or can you? If you've read the "Discipline of Programming" book of E. Dijkstra, you know that the first law he establishes there is the "there-are-no-miracles law" :-). So you may guess my position on this.

BTW, maybe I (or someone else) should email Mr. Stroustrup on this one, and see what he's got to say. It would be interesting, I guess, so maybe I'll do it anyway.

And now more comments


Let's continue in the commenting vein: sometime ago I was looking for web-frameworks in C++, and wanted even reimplement Java's Servlet classes in C++ (well, I didn't...). But in the last DDJ I saw an article**** about a C++ web-framework at last! Fortunately, I didn't implement the C++ servlet classes, because it was a really stupid idea! The Wt-framework ("witty" - http://www.webtoolkit.eu/wt/) seems to be rather like modern Java frameworks - GWT, ThinWire or Wicket - you define your application classes in C++, and the HTML rendering comes from the framework! In contrast to the Servlet specification, which is very low level and which nobody uses directly now! Thank God I was lazy! I'll have to try Wt out, perhaps there is an C++ alternative for web-programming anyway.

---
* http://ib-krajewski.blogspot.com/2007/07/google-solvers.html
** here he did basically the same but with Ruby in place of Python: http://butunclebob.com/ArticleS.UncleBob.SpeedOfJavaCppRuby
*** "Improving JVM scalability and performance": http://blog.chinaunix.net/u1/45382/showart_356477.html or http://go.techtarget.com/r/1950475/6108168
**** "Wt: A Web Toolkit": http://www.ddj.com/cpp/206401952

Thursday, 31 January 2008

C++ pocket lambda library, part 2


In the previous post in this series* I promised to tackle some more advanced topics from my pocket lambda library. To start with something, let us gratuitously choose "currying" first. Do you know what currying is? No, it has nothing to do with food, but rather with an american mathematician named, ehm..., Haskell B. Curry. In his formalization of the notion of a computable function (λ-calculus) he used (for simplicity's sake) only functions with one parameter. Come again? What about all the other functions? For this he used a trick: he defined a function which returns a new function where the first argument is fixed, and the second one remains unbound. When used recursively, we can reduce any function of n-arguments to n functions of 1 argument! Mathematics can be as cool as programming sometimes!

I bet you've seen (and used) it before! Yes, STL provides bind1st and bind2nd functions, which are doing exaclty that: currying! In other languages like Python, Perl, Ruby, Haskell, etc, it's possible too, though sometimes through a library extension. Groovy supports IMHO the most explicite (and cool) form:
    def triple_it = {x,y -> x*y }.curry(3);

1. Our task


What we want to do is to extend the STL binder such that they would work the _$1 placeholders. I think of something like the following:
    for_each(vec.begin(), vec.end(), bind(countVector, 'X', 1.222, _$1));
    for_each(vec.begin(), vec.end(), bind(countVector1, _$1, 1.222, 'Y'));
    for_each(vec.begin(), vec.end(), bind(countVector2, _$1));

    for_each(vec.begin(), vec.end(), bind(pr_sinus, _$1*2));
    const float pi = 3.14; // well, not exactly ;-)
    for_each(vec.begin(), vec.end(), -bind(sinus, _$1*(pi/180.0)) ); 
We assume here that the bind function is pulled in by the appropriate namespace definition, as I want avoid to have to write it like kmx::lambda::bind(sinus, kmx::lambda::_$1). In fact, I never tried out the fully qualified form, shame on me :-(((.

How can we do that? Well there's no need to reinvent the wheel - Boost library already has it, and it's even a part of the C++0x TR.1 standard library extension (tr1::bind). So we can look at the code, or even read about the techniques needed in the implementation**. So if you want, you can spare yourself this post and read ** instead!


2. Basic mechanisms


Well, here is the bind function for the 2 arguments case:
    // 2 args
    template <class F, class A1, class A2>
        binder<F, list2<A1, A2> > bind(F f, A1 a1, A2 a2)
    {
        typedef list2<A1, A2> list2_type;
        list2_type list(a1, a2);
        return binder<F, list2_type>(f, list);
    } 
What is it doing? Basically it stores the arguments to be bound in a custom argument list (class list2<>). Then the function and its arguments are used to create the instance of the actual binder class:
    template <class F, class List> class binder : public lambda_expr
    {
        F m_f;
        List m_list;

     public:
        binder(F f, List list): m_f(f), m_list(list) {}

        // OPEN TODO --> only working for void funct!!!
        template <class A1> void operator() (A1 a1)
        {
            list1<A1> list(a1); // store the actual arg
            m_list(m_f, list); // forward to curried funct: m_f+m_list
        }
    }; 
What is it doing now? It's a functor accepting (in the H.B.Curry's true manner) only one argument. Which one? In the context of an STL algorithm it will be the current value of the iterator. So our task is to sort out to which of the arguments of a function this iterator is bound. Take our previous example: for_each(vec.begin(), vec.end(), bind(countVector1, _$1, 1.222, 'Y')). Here the iterator has to be bound to the first argument of the function - 1.222, and 'Y' to the second and third ones. The binder object stores the actual argument in the custom argument list (class list1<>) and invokes the function m_f in the context of the bound arguments m_list, remembering the current argument in the custom argument list class list1<>. All this is accomplished by heavy use of the listN<> classes, to which we turn our attention now:
    template <class A1, class A2> class list2
    {
        // args: one of them is a placeholder!
        //  -- list1 will detect it!
        A1 m_a1;
        A2 m_a2;
     public:

       list2(A1 a1, A2 a2): m_a1(a1), m_a2(a2) {};

       // apply to arguments and placeholders!
       template <class F, class List1>
           void operator() (F f, List1 list1)
           {
               f(list1[m_a1], list1[m_a2]);
           }
    }; 
Well, list2<> doesn't do that much, it invokes the curried function, but the detection of bound arguments is redirected to the most important class here: list1<>! Let us have a look at it:
    template <class A1> class list1
    {
        A1 m_a1;

     public:
        explicit list1(A1 a1): m_a1(a1) {}

        // if placeholder:
        A1 operator[] (placeholder<1>) const { return m_a1; }

        // not placeholders: return the ball
        template <class T>
            T operator[] (T val) const { return val; }
    }; 
Well, this isn't very complicated: complier will detect when a placeholder was placed and use then the current argument (i.e. the iterator). In other cases, the stored argument value will be used, i.e. the value used to curry the function f. As the value is stored in the listN<> class, it is done via a trick: the listN<> class tries to access the placeholder's _$1 value by using the index operator of the list1<> class, but in non-placeholder cases the index value is simply returned to listN<> to be used as n-th argument (a kind of rebound!).

For the sake of completeness, i.e. in case of bind(sinus, _$1) (who'd need something like that?), we need the function call operator in the list1<> class:
    template <class A1> class list1
    {
       ...
       // apply to arguments and placeholders!
       template <class F, class List1>
           void operator() (F f, List1 list1)
           {
               f(list1[m_a1]);
           }
    };
To bind 3-argument functions we need two more templates to be added: the list3<> class and the bind(F f, A1 a1, A2 a2, A3 a3) function, for 4 arguments another two, and so on, and on... But I don't think anyone should need more than 5 arguments in their functions, do you?

3. Extensions


With the above techniques we can write bind(countVector1, _$1, 1.222, 'Y') but not bind(countVector, _$1*2) or bind(sinus, _$1*(pi/180.0)). What can we do about this? Above we wondered about the bind(sinus, _$1) case, but here we can use it to our advantage. We extend the list1<> class like that:
    template <class A1> class list1
    {
       ...
        template <class T>
            T operator[] (Mul<T>& e) const { return e(m_a1); }
   };
So we can see that the list1<> class is indeed a central one! We extended its rebound mechanism to support the multiplication. Oh, uhm, that wasn't pretty! Why couldn't we simply use a general forwading here? The reason is, I left is as a TODO in code (shame on me :-((() but never came around to implement this. I tried the following:
    A1 operator[] (lambda_expr& e) const { return e(); }
but I didn't finish it, and I don't remember if it worked and if it didn't, why. It was almost one year ago and I don't remember all the details, sorry. OK, that could be done better, but (as I said in my previous post*) "it's a simple library". If you need another operation to be supported in the bind context, simply add it to the list1<>. It remains to be clarified if the simplicity of this library is an advantage, but some measurements were reported, which say that the many layers in a fully grown-up lambda library (like Boost) have a detrimental effect on the performance, because the code gets so complex that the optimizers cannot cope with it!*** And the compilation gets longer too. So maybe such a primitive implementation isn't totally in the wrong?
There is another extension I tried. Again we have to extend the central list1<> class:
    template <class A1> class list1
    {
       ...
       // bind a void member function e.g.: int (T::*)(void *)
       template <class T, typename Ret, class List1>
           Ret operator() (Ret(T::*f)(void), List1 list1)
           {
               return ((list1[m_a1])->*f)();
           }
    };
What does it do? It is supposed to be used like that:
    vector<SomeClass> vec(10);
    for_each(vec.begin(), vec.end(), bind(&SomeClass::compute(), _$1);  
So for each object in a collection its (void) member function will be called. But again, I don't know if it actually worked, as there is no testcase for that in my code (but I think it should). And not everything that's possible makes sense anyway: here the code is misleading, we'd rather like to express this with _$1->compute()!

4. Last words


Well, that's everything I can say about currying support in my library. In the next post(s) I'll show you how to support lambda expressions like: cout << "---" << _$1 << "\n", and how to access a member or a member function of an object from a collection. What else? Maybe some conditional lambda expressions and some general discussion? Look out.

A general question can be answered here: what about the code of my library? Will it be publicly available? And what about the TODOS? And the missing orthogonality? The anwer is, I don't want to (and haven't got time, for that matter) polish the rough edges and add some more orthogonality. It was a fun writing the library, it took me only a couple of days (about 4, I think) , it is simple, and it has shown me that you don't have to be scared of the template metaprogramming. Of course, I wasn't a novice with templates, but I expected more resistance from C++. Maybe it's because of the library's simplicity?

Whatever. This library is not ready, is not complete, and I leave it as it is now.

---
* http://ib-krajewski.blogspot.com/2007/12/c-pocket-lambda-library.html
** Chris Gibson, "How Do Those Funky Placeholders Work?", Overload 73: http://www.accu.org/index.php/journals/1397
*** C++0x proposal: "Lambda expressions and closures for C++" : http://www.research.att.com/~bs/N1968-lambda-expressions.pdf