$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Brian McNamara (lorgon_at_[hidden])
Date: 2004-03-02 06:42:52
Thanks for your comments.  A few quick replies to questions:
On Mon, Mar 01, 2004 at 10:10:15PM -0800, Jared Roberts wrote:
> I've been generally impressed with the design.  There are a few things 
> that bother me.  I dislike having to manually promote direct functoids 
> to full functoids.  This is particularly sticky if the functoid is 
> recursive, as above.  I worked around this at (A) by using a lambda 
> variable to hold the full functoid, but I would have thought there was a 
> better way.  If there is, I didn't see it in the documentation.  I also 
For recursion, you can always just say "make_full1(*this)", but that's
still a little big/ugly; it would be nice if you could just say
"*this".  Alternatively, you can define the whole algorithm inside
lambda and use "letrec" to create a recursive function definition.
> One thing in particular that seems to have been overlooked by some 
> others about the lambda variables is that they allow you to do a fair 
> amount of type inference!  Looking again at the quicksort example, 
> rather than worry about types, I just declared everything lambda and the 
> compiler was able to figure everything out.  This is true even for 
> qs_rec, which is bound to the full-functoid version of quicksort to be 
> used in the recursive step at (B).  FC++ is able to figure all this out, 
> even though qs_rec isn't bound when declared.  It's not quite "auto", 
> but it's pretty cool!
Indeed!  I'd never really considered FC++'s lambda/let as a stop-gap
solution for the proposed "auto" type inference, but it does kinda
accomplish this.
> (side note:  Is there any reason the lambda() has to be there at all? 
> It seems a bit silly to define a lambda and then immediately evaluate 
> it.  Shouldn't the let ideally be able to suffice here?)
Well, "let[...].in[...]" is a lambda expression, so you need some
operation to transform it into its value.  But yeah, wow,
   lambda()[ blah ]()
is pretty ugly/verbose, and I could easily make just
   blah()
(or something similar) work.  Good idea.
> The documentation isn't great.  [...]
> I'm still not sure, for example:  In the quicksort example again, at 
> (B), there is a recursive call "qs_rec[rights]".  Is this call 
> automatically lazy?  Or do I have to do something to it?  Earlier 
> versions of the code didn't have this part wrapped up in a lambda, and I 
> was able to do thunk1(qs_rec, rights), but I couldn't figure out what I 
> needed to do here.  My hunch is that I need to do nothing, but I 
> couldn't find anything that told me so for sure.
It is not lazy.  (More precisely, it is not lazy with respect to the
lists, which I think is what you want.  It is lazy in the sense that it
is a lambda expression, and thus will not get evaluated until the lambda
is evaluated.)
To fix it, just change
   qs_rec[lefts] %cat% (pivot %cons% qs_rec[rights])
to
   qs_rec[lefts] %cat% (pivot %cons% thunk1[qs_rec,rights])
Except, that I just tried it and this doesn't work.  Doh!  Here's a
comment in the library implementation:
   // FIX THIS: the thunkNs are not full functoids.  Oh well.  Until I find
   // a need to make them so, I'm not going through the effort.
So consider this a bug/oversight, and watch the library author
sheepishly slink away to fix it.  :)
-- -Brian McNamara (lorgon_at_[hidden])