
I've just made a first attempt to read through FC++ docs, and have some comments. I haven't read all of the posts in the recent review, so apologies if some of the issues are already known. The docs I used are those at http://www.cc.gatech.edu/~yannis/fc++/boostpaper/fcpp.html First, a motivating example: I wanted to find a vertex in BGL graph which has in degree of zero. This should be something as simple as (using lambda): find(vertices(g).first, vertices(g).end(), bind(in_degree, _1, g) == 0); but in_degree happens to have several overloads, all of which are templates, so just 'in_degree' won't work, and selecting the right variant via cast has it's own problems. So, I though FC++ would allow me to declare 'in_degree_f' object that will work for all kinds of graph. The documentation starts with: FC++ is a library for doing functional programming in C++. The library provides a general framework to support various functional programming aspects, such as higher-order[1] polymorphic[2] functions, The issues with this are: 1. When this is in context of proposed Boost.FC++ docs, one immediately wonders how this is different from Boost.Lambda. 2. The footnotes always break the regular flow of reading, so it's better not use them in the first sentence new user is likely to see. 3. higher-order polymorphic functions exists even without FC++. I think boost::bind is such a function: it takes function as argument and returns a function. So, this statement does not indicate what new FC++ brings (btw, I agree it brings something new). 4. If you think that average reader will think that 'polymorphic' == 'with virtual functions' you might want to use the word 'generic'. Later, you define 'functiod' and the definition applies just nice to functional objects everybody was using for quite some time. Again, you don't explain what FC++ brings. Later, you describe changes made during boostification. I really don't think new user would be interested in that. The above comments might sound like nit-picking, but what I try to say is: the instroduction does not say absolutely anything about why FC++ is worth looking at. The only new term there is 'lazy_list' and if reader doesn't know what's that already, he might not get even that. In section 2, you say: Programming in this pure style ensures referential transparency. and I don't know what "transparency" here means. Now, to section 4, "Overview". What I'd expect in this section is a bunch of examples, showing what I can do with FC++ which is not easily done using other tools. What I see, though, is: We could define a polymorphic functoid add_self(), which adds an argument to itself: // add_self( x ) means x + x If we can define such thing, I'd really like to see the definition, not commented out code. The you talk about lazy list, again for someone who has no idea what they are, it's hard to understand usefullness. I think you should either explain this with an example, or at worst give some link. E.g. "Why functional programming matters" makes some use of lazy lists, IIRC. The overview does on in largely the same style. You list supported functoids but don't give any explanations or example. Last comment on this section: plus(3,4) // 3+4 also minus, multiplies, etc. This does not look impressive. Can't I do "std::plus<int>(3,4)". I think one of the points of FC++ is that you don't need to specify the exact type. If so, you need to explicitly state that fact (and preferrable, even in the introduction). Now to the Section 5. Direct functoids enable the creation of functions Hmm.. is it precisely "enable". I suspect that "direct functoid" *is* the function. Or is direct functoid is some device which produces functions? I think the example with 'map' is not really good. First you say map takes a list and function. Then you give Haskell syntax and describe that syntax. After that you explain what's high-order and what's polymorhic. IMO, the Haskell syntax is just not necessary here. Later you say: Representing such a function in C++ is non-trivial Then, what about std::transform? If we forget that it works on iterators, not sequences (which is just detail) then it does exactly what you're after. I think it would be better if you write down properties of the function you want to create (polymorphic, can be passed as argument *itself*, allows to inter return type) and then immediately give an example. And example could be more reabably you use split the definition of 'result_type' like this: template <class F, class L> struct sig { typedef F::template sig<typename L::value_type>::result_type function_return typedef list< function_return > result_type; }; It might be better to use 'type' instead of 'result_type' since MPL uses 'type'. When you talk about monomorphic direct functoids, I wonder why you need 'c_fun_type'. Is it possible to make std::unary_function work? The section 6, "Indirect Functoids", makes me wonder if they are usefull at all. boost::function works very nice with me, and it also works with boost:bind. The secton 7, "Full Functoids" looks ok to me, though some examples would be good. At this point I've stopped reading documentatation, tried to write some code and got my 'in_degree_f' in a short time. There are some additional questions: 1. Maybe it makes sense to provide a helper base class for a case where return type is fixed, but argument types are not. Something like: class xxx_in_degree : public ret_type2<unsigned> { ... } ; 2. Do we need intermediate typedef? Won't boost::fcpp::full2<xxx_in_degree> in_degree_f; work just fine? 3. I have std::find_if(vertices(g).first, vertices(g).second, in_degree_f(_, g)); but I want to compare the return from 'in_degree_f' with zero, as in thes example: find(vertices(g).first, vertices(g).end(), bind(in_degree, _1, g) == 0); How do I do that? When I try: std::find_if(vertices(g).first, vertices(g).second, lambda(X)[ in_degree_f[X, g] %equal% 0]); I get a lots of errors, starting with: fcpp/signature.hpp:114: error: invalid use of undefined type `struct boost::fcpp::impl::XEqual::sig<size_t, int>' The complete example is at http://zigzag.cs.msu.su:7813/bgl.cpp if needed. Also, it would be *really* nice if lambda syntax in FC++ and Boost.Lambda was compatible. I'll print and read your paper on syntax today, but no matter how big semantic differences are, learning/using two different syntaxes is a bad idea. These are all comments for now. Hope they make sense. - Volodya
participants (1)
-
Vladimir Prus