Skip to content

Feature functional tooling start - #74

Open
Sqeaky wants to merge 9 commits into
masterfrom
feature-functional-tooling-start
Open

Feature functional tooling start#74
Sqeaky wants to merge 9 commits into
masterfrom
feature-functional-tooling-start

Conversation

@Sqeaky

@Sqeaky Sqeaky commented Aug 14, 2020

Copy link
Copy Markdown
Member

This PR isn't complete yet, but when done it will include a basic set of tools for functional programming.

@Sqeaky
Sqeaky requested a review from MakoEnergy August 14, 2020 05:01
@Sqeaky Sqeaky added this to the 1.0 milestone Aug 14, 2020
@Sqeaky

Sqeaky commented Aug 14, 2020

Copy link
Copy Markdown
Member Author

I have three different mechanisms for implementing a small set of functional tools. I want to get input on these and discuss what the best way forward is.

I think the 3 parameter functions has the least promise. These were the simplest to implement because they just use normal template parameter deduction, but specify the type as a parameter also the value of that parameter to matter. for now it just appends to the output set of each function. This isn't idiomatic but could be useful if we go this way.

The 2 parameter functions like the current Convert and Reject work, and are simple. They can be combined in interesting ways with the currying functions to achieve just about anything. I think nesting a bunch of function can lead to gross syntax and I think that is likely with this.

The 2 parameter select function has a bunch of gross machinery behind it. It should be able to fully interoperate with the two parameter functions however we want, but it can also curry itself. If given a predicate and no data it will return a function that accepts data and performs the previously setup selection. This has the drawback of being a bit complex, but I ability to curry without needing to explicitly call a seperate function makes it easier to construct a cleaner syntax for chaining transformations. I am experimenting with this in the Pipe class, which mostly noise right now.

@Sqeaky

Sqeaky commented Aug 14, 2020

Copy link
Copy Markdown
Member Author

I know this is really rough, most of it can be ignored. The main work and experiments are in "FunctionalTools.h" and "FunctionalToolsTests.h"

@MakoEnergy MakoEnergy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finished my initial pass. Aside from the obvious stuff of needing to document and wondering where you are going with the piping...it looks good thus far.

@MakoEnergy MakoEnergy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finished second pass of the current state of the code.

Comment on lines +124 to +127
decltype(auto) Name(const CVIncomingContainerType& IncomingContainer) \
{ \
return StructName{}(std::forward<const CVIncomingContainerType&>(IncomingContainer)); \
} \

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You aren't using a universal reference for the parameter here, so I don't think you need the forward.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I need to spend time cleaning this kind of noise up. This is from repeated tests/refactors and never cleaning it up.

Comment on lines +85 to +90
decltype(auto) Name(const CVIncomingContainerType& IncomingContainer, PredicateType Predicate) \
{ \
return StructName<>{} \
(std::forward<const CVIncomingContainerType&>(IncomingContainer), \
std::forward<PredicateType>(Predicate)); \
} \

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like below, no need for forward when not using universal reference.

START_FUNCTOR_END_CONTAINER_TO_DATA_AUTOCURRY(MinStruct)
template<typename CVIncomingContainerType, typename PredicateType>
[[nodiscard]] constexpr
decltype(auto) operator() (CVIncomingContainerType&& IncomingContainer, PredicateType Predicate) const

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure which is intentional, but it's odd that you are passing predicate by const reference in the function above this one, but by value in this one. AND you are forwarding this one (which again, no universal reference so no need).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will try to change the predicates to universal references.

using IncomingContainerType = std::decay_t<CVIncomingContainerType>;
using namespace ContainerDetect;
static_assert(IsRange<IncomingContainerType>(),
"Mezzanine::MinMax only determines the Min from containers or ranges.");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this message should say "Mezzanine::Min" instead of "MinMax".

Comment on lines +222 to +228
auto Results = std::minmax_element(IncomingContainer.cbegin(), IncomingContainer.cend());
return std::pair{*Results.first, *Results.second};
}
else
{
auto Results = std::minmax_element(IncomingContainer.cbegin(), IncomingContainer.cend(), Predicate);
return std::pair{*Results.first, *Results.second};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/nit Is use of std::make_pair appropriate here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

Comment thread include/FunctionalPipe.h Outdated
Comment on lines +52 to +54
namespace Mezzanine
{
namespace Functional {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/nit I find your lack of consistency....disturbing.

Comment thread include/FunctionalPipe.h

// Convert this when assiging to strongly typed storage.
[[nodiscard]] constexpr
operator auto() const

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type is cleanly known. No need for "auto".

if constexpr( HasReserve<ReturnContainerType>())
{ Results.reserve(HowMany); }

for(SizeType Counter{0}; Counter<HowMany; Counter++, Copying++)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/nit Some spaces around the operator for visibility would be nice.

if constexpr( HasReserve<ReturnContainerType>())
{ Results.reserve(HowMany); }

for(SizeType Counter{0}; Counter<HowMany; Counter++, Copying++)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/nit Same nit as before.

Comment on lines +817 to +822
if constexpr(HasPushBackValue<ReturnContainerType>())
{ Results.push_back(*Copying); }
else if constexpr(HasInsertValue<ReturnContainerType>())
{ Results.insert(*Copying); }
else if constexpr(HasAddValue<ReturnContainerType>())
{ Results.add(*Copying); }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all of the operations that copy the elements, should we static_assert to verify the element is copy constructable? I also have the slightest bit of concern about situations where a moving variant of these functions may be selected instead of the copy.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are const iterators pointing into a const container, moving shouldn't be possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants