Boost logo

Boost :

From: Brian McNamara (lorgon_at_[hidden])
Date: 2003-10-08 18:59:34


On Wed, Oct 08, 2003 at 07:27:43PM -0400, David Abrahams wrote:
> Makes sense, but it seems like F(Y) could be equivalent to F[Y] where
> Y is a lambda_arg.
...
> which makes the F(Y) syntax not just viable, but desirable, it
> seems to me.

(I address your suggestion shortly, after a more general digression.)

There are problems with the approach of just using operator(). The
most convincing one, IMO, is that right now you can do

   int print_and_inc( int x ) {
      cout << x << endl;
      return x+1;
   }
   // now imagine "p_a_i" is the corresponding functoid

   // here is a nullary functoid which prints 3 and returns 4 when
   // invoked:
   lambda()[ p_a_i[3] ]

If you eliminate operator[] and overload operator() to take on both
semantics, you can no longer easily "delay side effects" using lambda:

   // Whoops, prints now, rather than later when someone invokes it.
   lambda()[ p_a_i(3) ]

As you say, you could have f(Y) mean f[Y] *iff Y is a lambda_var*. But
then this starts to interfere with other things. For example, the
identity function "id" always returns its argument unchanged. You can
replace any expression "expr" with "id(expr)" without changing the
semantics of your program. Thus, currently,

   // function to add one (also spelled "inc" or "plus(1)")
   lambda(X)[ plus[1,X] ]

   // equivalent
   lambda(X)[ plus[1,id(X)] ]

But if you start overloading () for use with lambda, the "equivalent"
code above breaks. (This example is a little contrived, but I do think
more general examples along these lines may arise.)

Finally, we like the explicitness of

 - if you call f with square brackets, the call gets delayed
 - if you call f with round brackets, the call happens now

compared to approaches like

 - if you call f, and somewhere nested inside one of f's arguments is a
   lambda expression, then the call to f gets delayed, else the call
   happens now

There are clearly trade-offs among all of the interesting points in the
design space. Our goal was to try to choose the point which is least
likely to cause accidents (where "accidents" means something like: your
program compiles warning-free, but it exhibits behavior other than the
one you intended).

-- 
-Brian McNamara (lorgon_at_[hidden])

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk