On Mon, 5 Jan 2004, Lars Gullik Bjønnes wrote:

> If you want obfuscation have a look at this.
> (no, I won't actually admit that this is obfuscated.)
> (I find especially the logical_and usage a bit funny :-) )

Ok... I read about half of it before I got tired... My conclusion is that 
Lars is essentially correct; I was surprised how easy it was to understand 
it in general now. However, a few general comments (although perhaps 
more about C++ in general than this particular code) ...

Look at this code:

boost::function<bool(Converter const & c)>
compare_Converter(string const & from, string const & to)
{
       return bind(logical_and<bool>(),
                   bind(equal_to<string>(),
                        bind(&Converter::from, _1),
                        from),
                   bind(equal_to<string>(),
                        bind(&Converter::to, _1),
                        to));
}


and look at this code that's been de-indented and compressed...

boost::function<bool(Converter const & c)>
compare_Converter(string const & from, string const & to)
{
  return bind(logical_and<bool>(), bind(equal_to<string>(), 
bind(&Converter::fr\om, _1), from),
                bind(equal_to<string>(), bind(&Converter::to, _1), to));
}

Should the code readability really depend _this_ much on the indenting?

Maybe the code is not obfuscated, but the statements are definitely 
more complicated now...  compare this to (I still don't know how to write 
this code, so ???? stands for some declaration of a bound object):

boost::function<bool(Converter const & c)>
compare_Converter(string const & from, string const & to)
{
        bind????? fromConvertMatch_p =
                bind(equal_to<string>(), bind(&Converter::from, _1), from);
        bind????? toConvertMatch_p =
                bind(equal_to<string>(), bind(&Converter::to, _1), to));
        return bind(logical_and<bool>(), fromConvertMatch_p, toConvertMatchP);
}

where the appended '_p' is in honour of lisp's '-p' for 'predicate'.


If we wanted more compact statements, couldn't we rewrite
        for ( ; par != end; ++par) {
                if (par.pit() == pit)
                       break;
        }

into something like this
        while ( par != end && !(par.pit() == pit) )
                ++par;

but I think the first form is easier to read.


Anyway, the function compare_Converter() was still readable thanks to the 
indentation, but piece of code from LyXTextClass:LyXTextClass() is over 
the top (note that I changed the indentation to keep one of the lines 
from wrapping):

        return find_if(layoutlist_.begin(), layoutlist_.end(),
                       bind(equal_to<string>(),
                            bind(&LyXLayout::name,
                                 bind(&LyXLayout_ptr::operator->, _1)),
                            name))
                 != layoutlist_.end();

actually... I'm not sure I've got the indentation correct here... 


Finally, the lambda thing looks cool... while trying to find out 
about bind(...), I found this link:
        http://www.boost.org/libs/lambda/doc/ar01s03.html

and based on that, it looks like compare_Converter() could be written as:

bool BranchList::remove(string const & s)
{
        List::size_type const size = list.size();

//      list.remove_if(var(s) == bind(&Branch::getBranch, _1));  // a)

//      list.remove_if(s == bind(&Branch::getBranch, _1));       // b)

        list.remove_if(s == _1.branch_);                         // c)

//      list.remove_if(s == getBranch(_1));                      // d)

        return size != list.size();
}

I'm not sure if alt. (a) works, and although I like alt. (b), it doesn't 
use the getBranch() method. In that case, I think alt (d) should work.

/Christian

-- 
Christian Ridderström                           http://www.md.kth.se/~chr



Reply via email to