I was intrigued by this question, so I had to try it out because it kind of reminded me of lisp which I absolutely loved. Example from that question:
auto list = [](auto ...xs) {
return [=](auto access) { return access(xs...); };
};
auto length = [](auto xs) {
return xs([](auto ...z) { return sizeof...(z); });
};
int main()
{
std::cout << length(list(1, '2', "3")); // 3
}
Eventually I got some more polymorphic lambdas which further made it look like lisp:
auto l = list(-1, 2, 3, 4, 5, 6);
cons(unary::map(unary::inc)
(binary::map(binary::add)
(cdr(l), 1)), list(12, 13, 14, 15, 16)))
// just an example, it doesn't really look that much like lisp, but still I was amused
Now, if I wanted a print function, which I did, I had to write it like:
auto print = [](auto i)
{
std::cout << i << " ";
return i;
};
and then map it to each of the parameters in the parameter pack.
That's not really lisp-like and I'm wondering if there's a way to recursively go through the parameter pack using car/cdr style that's used in lisp. Obviously the closure that list lambda returns would have to be used.
Also, I'm aware that parameter packs shouldn't really be used for things like this.
EDIT:
I managed to implement recursive printing using templates:
template<typename First>
void print_helper(First f)
{
std::cout << f << std::endl;
}
template<typename First, typename... Rest>
void print_helper(First f, Rest... r)
{
std::cout << f << " ";
print_helper(r...);
}
template<typename Lambda>
void print(Lambda l)
{
l([=](auto... elements)
{
print_helper(elements...);
});
}
But now I'm having problems with recursive functions that return values. Let's say I want to have a filter/remove-if function which returns a list of elements which meet the requirement given by the provided predicate. Currently I'm using a std::pair (just like in the linked question) per element, which contains a flag if the pair should be skipped while printing. Is there a way to actually return the list of only those elements without the need for flags?