Boost logo

Boost :

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])

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