// a function takes types and gives back a type. calling one is itself a type // it sees nothing but its parameters, and every argument must be a ::decltype so it carries a value ::define< ::name<'s', 'q', 'u', 'a', 'r', 'e'>, ::parameters<::name<'x'>>, ::sequence< ::return<::decltype(::product<::value_of<::name<'x'>>, ::value_of<::name<'x'>>>)>::commit > >::commit; ::emit< ::invoke_result_t< ::name<'s', 'q', 'u', 'a', 'r', 'e'>, ::arguments<::decltype(::difference<'F', 'A'>)> > >::commit; // a function can return anything a type can be, which includes a tuple of characters ::define< ::name<'g', 'r', 'e', 'e', 't'>, ::parameters<>, ::sequence< ::return< ::tuple< ::integral_constant<::char, ::difference<'h', '\0'>>, ::integral_constant<::char, ::difference<'e', '\0'>>, ::integral_constant<::char, ::difference<'y', '\0'>> > >::commit > >::commit; ::emit<::invoke_result_t<::name<'g', 'r', 'e', 'e', 't'>, ::arguments<>>>::commit; // a function that never returns gives back ::void, and emitting ::void prints nothing ::define<::name<'n', 'o', 'p'>, ::parameters<>, ::sequence<>>::commit; ::emit<::invoke_result_t<::name<'n', 'o', 'p'>, ::arguments<>>>::commit; // a return inside a branch still leaves the function ::define< ::name<'s', 'i', 'g', 'n'>, ::parameters<::name<'n'>>, ::sequence< ::enable_if_t< ::less<::value_of<::name<'n'>>, ::difference<'A', 'A'>>::value, ::sequence<::return<::decltype(::difference<'A', 'B'>)>::commit> >::commit, ::return<::decltype(::difference<'B', 'A'>)>::commit > >::commit; ::emit< ::invoke_result_t<::name<'s', 'i', 'g', 'n'>, ::arguments<::decltype(::difference<'A', 'Z'>)>> >::commit;