diff options
author | Adrian Kummerlaender | 2015-03-02 19:41:58 +0100 |
---|---|---|
committer | Adrian Kummerlaender | 2015-03-02 19:41:58 +0100 |
commit | b083df7e22359f2a8fd643d5d50e5a760b542b88 (patch) | |
tree | dabf95043f22989d930f9ac6c234580769ea9f26 | |
parent | a3d0aabcaea0b7f6c194fa3adb46a3b31bb43d9a (diff) | |
download | blog_content-b083df7e22359f2a8fd643d5d50e5a760b542b88.tar blog_content-b083df7e22359f2a8fd643d5d50e5a760b542b88.tar.gz blog_content-b083df7e22359f2a8fd643d5d50e5a760b542b88.tar.bz2 blog_content-b083df7e22359f2a8fd643d5d50e5a760b542b88.tar.lz blog_content-b083df7e22359f2a8fd643d5d50e5a760b542b88.tar.xz blog_content-b083df7e22359f2a8fd643d5d50e5a760b542b88.tar.zst blog_content-b083df7e22359f2a8fd643d5d50e5a760b542b88.zip |
Expanded section on _templates as functions_
* added information on partial template specialization and `tav::Eval`
* added title outline of remaining sections
-rw-r--r-- | articles/2015-02-27_using_scheme_as_a_metaphor_for_template_metaprogramming.md | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/articles/2015-02-27_using_scheme_as_a_metaphor_for_template_metaprogramming.md b/articles/2015-02-27_using_scheme_as_a_metaphor_for_template_metaprogramming.md index 0cde18d..4ab74ee 100644 --- a/articles/2015-02-27_using_scheme_as_a_metaphor_for_template_metaprogramming.md +++ b/articles/2015-02-27_using_scheme_as_a_metaphor_for_template_metaprogramming.md @@ -92,9 +92,57 @@ using Every = Fold< ~~~ {:.language-cpp} -If we ignore the need to explicitly declare the predicate as a _template template parameter_ i.e. as a function this example is very simmilar to its _Scheme_ equivalent. Concerning the function used to fold the list it is actually less verbose than the _Scheme_ version of `Every` as we can directly pass `tav::And` instead of wrapping it in a lambda expression, which is required in _Scheme_ because it's `and` is a macro. +If we ignore the need to explicitly declare the predicate as a _template template parameter_ i.e. as a function this example is very simmilar to its _Scheme_ equivalent. Concerning the function used to fold the list it is actually less verbose than the _Scheme_ version of `Every` as we can directly pass `tav::And` instead of wrapping it in a lambda expression as is required in _Scheme_ [^1]. + +Sadly the actual implementations of e.g. `tav::Fold` are not as easily expressed. The recursive nature of folding a list or even constructing its underlying pair based structure using the variadic `tav::List` requires partial template specializations which are not allowed for template aliases[^2]. + +~~~ +template < + template<typename, typename> class Function, + typename Initial, + typename Pair +> +struct fold_pair { + typedef Function< + Car<Pair>, + Eval<fold_pair<Function, Initial, Cdr<Pair>>> + > type; +}; + +template < + template<typename, typename> class Function, + typename Initial +> +struct fold_pair<Function, Initial, void> { + typedef Initial type; +}; +~~~ +{:.language-cpp} + +While the listing of `tav::detail::fold_pair` shows how the partial specialization of its `Pair` parameter allows recursion until the list ends[^3], it also forces us to define it's actual type in terms of a public `type` member `typedef`. Such a member type definition can lead to cluttering the code with `typename` keywords which is why [TypeAsValue] employs a simple `tav::Eval` template alias to hide all `typename *::type` constructs. + +~~~ +template < + template<typename, typename> class Function, + typename Initial, + typename List +> +using Fold = Eval<detail::fold_pair<Function, Initial, List>>; +~~~ +{:.language-cpp} + +Hiding member type defintions behind template aliases enables most _higher_ functionality and applications built using it's functions to be written in a reasonably minimalistic - _Scheme_ like - fashion as we can see in e.g. the listing of `Every`. This also explains why `tav::Pair` recursively defines it's own type, as we would otherwise have to be quite careful where to resolve `tav::Eval`. + +## Partial function application + +## Examples + +## Summary [^0]: ISO C++ Standard draft, N3797, § 3.9.1 _Fundamental types_, Section 7 +[^1]: `and` needs to be wrapped in anonymous function in _Scheme_ because it is not a function but a macro +[^2]: ISO C++ Standard draft, N3797, § 14.5 _Template declarations_, Section 3 +[^3]: _TypeAsValue_ currently represents _Scheme_'s empty list `'()` as `void` [appropriate article]: /article/a_look_at_compile_time_computation_in_cpp/ [ConstList]: /page/const_list/ |