Boost logo

Boost Users :

Subject: Re: [Boost-users] [boost] [Fit] formal review starts today
From: paul Fultz (pfultz2_at_[hidden])
Date: 2016-03-08 16:43:09


>> >>
>> >> Quick Start:Function Objects
>> >>
>> >> "We can make it behave like a regular function if we
> construct
>> the class
>> >> as a global variable."
>> >>
>> >> What about a non-global
>> >>
>> >> sum_f sum = sum_f();
>> >>
>> >> makes 'sum' not behave like a regular function other
> than the
>> fact that
>> >> the variable 'sum' may eventually go out of scope ?
>> >>
>> >
>> > In C++, a regular function is always global, there is no such
>> thing as local
>> > function(sans gcc extensions).
>>
>> My point is that the non-global 'sum' in my example above
> behaves just
>> as much like a regular function as your global 'sum'. You may
> want to
>> promote the idea of global function objects but I think that this is
>> personally a bad idea. IMO global variables of any kind are to be
>> avoided.
>>
>> It is quite common in several modern C++ libraries to declare functions as
>> global objects. There are many advantages to this. Why do you believe it
>> should be avoided? Especially since it has the same effect as a free
>> function.
>> DO you believe free function should be avoided as well?
>
> Global objects, whether functions or data, increases the chances for
> name clashes. Also accessing global data increases the chances for
> errors in a multi-threaded environment.
>
> Free functions can be in a namespace, as the standard library functions
> are in the 'std' namespace. This helps greatly in avoiding name

> conflicts.

By global variables, I mean defined at the namespace level, not solely at the
global namespace level. So functions using BOOST_FIT_STATIC_FUNCTION can be
defined within a namespace. Also, the function objects are `const` so there
isn't an issue from multithreaded environments.
>
>>
>>
>>
>> >
>> >
>> >>
>> >> Quick Start:Lambdas
>> >>
>> >> Why do we need both BOOST_FIT_STATIC_LAMBDA and
>> >> BOOST_FIT_STATIC_LAMBDA_FUNCTION ? I would seem that
>> >> BOOST_FIT_STATIC_LAMBDA_FUNCTION would be adequate and
>> >> BOOST_FIT_STATIC_LAMBDA is just redundant, mimicking lambda
>> syntax to no
>> >> purpose.
>> >>
>> >
>> > BOOST_FIT_STATIC_LAMBDA_FUNCTION and BOOST_FIT_STATIC_FUNCTION
>> both define a
>> > function at global scope, and can only be used at global scope,
>> whereas
>> > BOOST_FIT_STATIC_LAMBDA can be used to constexpr initialize local
>> variables
>> > as
>> > well.
>>
>> It might be good to add that when the end-user first encounters
>> BOOST_FIT_STATIC_LAMBDA, because the name does not suggest
>> initialization of local objects. Furthermore I cannot imagine why one
>> would want to use it to initialize a local object,
>>
>>
>> Really? You just said that you would prefer avoiding global functions.
>
> I mean that for local objects I do not see the reason why I would ever
> use BOOST_FIT_STATIC_LAMBDA instead of initializing local objects in the
> normal C++ way(s). If this is not the case you need to explain what
> problem(s) BOOST_FIT_STATIC_LAMBDA solve in initializing local data
> which ordinary C++ initialization of local data could encounter. If
> there aren't any problems BOOST_FIT_STATIC_LAMBDA solves in initializing

> local data I see no purpose for its existence.
>

Well, they can still be passed to constexpr functions, even if they are local,
I probably shouldn't discuss BOOST_FIT_STATIC_LAMBDA in the Quick Start guide
because its usage is not quite as a common.

>>
>> so you might want to
>> explain the benefit of doing so as opposed to the normal syntax for
>> creating a lambda function.
>>
>>
>> Maybe the quick start guide isn't the place for this in the first
> place.
>
> I would hope to convince you that a good Overview of your library should
> come first and then all the Quick Start guides, tutorials, examples etc.
> would make much more sense once your end-user understands what your

> library really does in terms of at least the main general functionality.

I usually start with the Quick Start guide with a library in order to get an
understanding of what components are in the library and what they can do, then
I start delving into the other components from there. Thats what I am showing
in the Quick Start guide.

I guess people have different ways of learning a library. I wonder what is
needed to be explained better in a initial overview of the library.

>
>>
>>
>> > In fact, BOOST_FIT_LIFT uses this since it is not always clear
> what
>> > context the user might call BOOST_FIT_LIFT.
>> >
>> >
>> >>
>> >> Quick Start:Overloading
>> >>
>> >> The overloading adaptors show two or more lambda functions.
> Can
>> they
>> >> also work with function objects ? Or a mix of lambda
> functions and
>> >> function objects ? In fact all the reamining Quick Start
> topics
>> show
>> >> examples with lambda functions. Do they also work with
> function
>> objects ?
>> >>
>> >
>> > Yes it can be used with function objects. I probably should show
>> an example
>> > of
>> > that as well. I used the lambdas because of the terseness of
> them.
>>
>> Evidently the adaptors can be used with any Callable. I think you
>> should
>> make that point very strongly and show that in examples also.
>>
>>
>> Agreed.
>>
>>
>> >
>> >
>> >>
>> >> Quick Start:Variadic
>> >>
>> >> I do not understand what 'We can also make this print
> function
>> varidiac,
>> >> so it prints every argument passed into it.' means ?
>> >>
>> >
>> > I'll try to explain that better, but basically it will print
> each
>> argument,
>> > so:
>> >
>> > print("hello", 5); // Will print "hello" and
> 5
>>
>> I wouldn't associate that with the word 'Variadic' but I do
> think you
>> need to explain that more clearly.
>>
>>
>> I always understood variadic to mean taking a variable number of
>> arguments. What do you understand variadic to mean?
>
> Your terminology is fine, but I always think of variadic in terms of
> variadic templates or variadic macros. After all your not making the
> print function variadic in the sense of taking a variable number of

> arguments.

Yes, I am, so I probably need to make that more clear in the

documentation.

> The simple_print functionality is any of 3 different lambda > functions, with 'conditional' picking the first one that is callable and
>
> 'fix' passing in the callable as the first parameter. So I really
> don't
> understand what 'by' does here in printing each argument irregardless of
>
> your 'Variadic' terminology. You need invoking examples and then show
> what the output would be for each invocation, and then it would be

> easier for me and others to understand what 'by' does in this situation.
>

Yep, that part needs to go into more in-depth.

>>
>>
>> >
>> >
>> >>
>> >> I do not think the Quick Start explains very much since it is
>> dealing
>> >> with adaptors of which we know almost nothing and the
>> explanation for
>> >> these adaptors and what they actually do is very terse.
>> >
>> >
>> > Probably can expand the explanation of adaptors a little more.
>>
>> Good idea. What do adaptors create ?
>>
>>
>> They create a function.
>>
>> Different function objects I would
>> imagine ? In that case how about the explanation that adaptors take
>> Callables as input and generate function object types that adapt the
>> original functionality of one or more Callables to some other purpose.
>>
>>
>> The examples are already show taking Callables. Are you suggesting I
>> show an example taking a member function or something?
>
> Global/static function, member function, std::function, boost::function,
> Boost Phoenix and/or Boost lambda function objects, instantiated
> template functions. My point is that you should show your library
> functionality working with as many types of Callables as possible.
> Instead your doc suggests that function objects and lambda functions are
> the only type which can be passed to your library's functionality and

> you enforce this view by your examples.

I'll try to do that.

>
>>
>> >
>> >
>> >>
>> >> In the 'Signatures' section of the Overview I read:
>> >>
>> >> "All the functions are global function objects except
> where an
>> explicit
>> >> template parameter is required." I honestly don't
> know what this is
>> >> supposed to mean. Does this refer to when function objects
> are
>> referred
>> >> to as parameters to the adaptors, functions, and utilities of
>> the library
>> >> ?
>> >>
>> >
>> > I don't understand what you are asking. It means that the
>> function is
>> > written
>> > like this in the documentation:
>> >
>> > template<class IntegralConstant>
>> > constexpr auto if_(IntegralConstant);
>> >
>> > But its actually a function object like this in the code:
>> >
>> > struct if_f
>> > {
>> > template<class IntegralConstant>
>> > constexpr auto operator()(IntegralConstant) const;
>> > };
>> > const constexpr if_f if_ = {};
>> >
>> > However, `if_c` is written like this in the documentation:
>> >
>> > template<bool B, class F>
>> > constexpr auto if_c(F);
>> >
>> > It requires the bool `B` template parameter explicity. So in the
>> code it is
>> > written as a function and not as a function object.
>>
>> I don't understand to what you are referring when you say
> 'function'.
>> Are you talking about adaptors in your library, functions in your
>> library, or what ?
>>
>>
>> I am talking about all functions that are defined in the library, that
>> includes adaptors as well. I am not sure how to make that clearer.
>>
>> Please try to understand that your use of the word
>> 'function' is very broad but that the word 'function'
> in C++ has a much
>> narrower meaning.
>>
>>
>> By function, I mean something like in the example:
>>
>> template<class IntegralConstant>
>> constexpr auto if_(IntegralConstant);
>>
>> I think everyone agrees that is a function in C++.
>

> I call that a function template.

Which is a family of functions.

> My definition for 'function' is not the >
> same as yours. I know you feel differently but please realize that the
> term 'function', to mean any and every type of callable in C++, is not a
>
> universally agreed on terminology. I would bet that for the vast
> majority of C++ programmers a function is:
>

> ReturnType FunctionName(ZeroOrMoreFunctionParameters);

Yes, which can happen at class scope or namespace scope, and it can also

be templated.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net