Last active
August 29, 2015 14:02
-
-
Save cppljevans/01e23df914916ea7d16e to your computer and use it in GitHub Desktop.
Prototype of lisp like lambda's based on Dionne's post "Efficient tuple implementation"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Purpose: | |
// Test if the code posted here: | |
/* | |
http://article.gmane.org/gmane.comp.lib.boost.devel/251897 | |
*/ | |
// With headers: | |
/* | |
From: Louis Dionne <ldionne.2@gmail.com> | |
Newsgroups: gmane.comp.lib.boost.devel | |
Subject: Efficient tuple implementation | |
Date: Sat, 7 Jun 2014 02:18:47 +0000 (UTC) | |
Lines: 89 | |
Approved: news@gmane.org | |
Message-ID: <loom.20140607T041645-909@post.gmane.org> | |
*/ | |
// can be extended to have "tagged" tuples | |
// where the tag is the initial element in | |
// the tuple and is some code for the operation to be | |
// performed with the remaining elements, somewhat | |
// like the "Polish prefix" notation mentioned here: | |
/* | |
http://en.wikipedia.org/wiki/Lisp_%28programming_language%29 | |
*/ | |
//Result: | |
// gcc4.8.1:fails compile | |
// clang3.4:passes compile. | |
// | |
#include <iostream> | |
enum op_enum | |
{ op_or //or operation | |
, op_and //and operation | |
}; | |
template<op_enum OpTag> | |
struct op_t | |
//tag for an operator. | |
; | |
template<> | |
struct op_t<op_or> | |
{ | |
typedef bool result_type; | |
}; | |
template<> | |
struct op_t<op_and> | |
{ | |
typedef bool result_type; | |
}; | |
auto op_ator_rands | |
= [] | |
( auto op_v //the operator tag. | |
, auto ...operands //the operands for the tagged operator. | |
) | |
{ | |
return [=](auto access) { return access(op_v, operands...); }; | |
}; | |
auto head = [](auto xs) | |
{ | |
return xs([](auto op_v, auto... operands) { return op_v; }); | |
}; | |
enum op_nullary | |
{ op_bool //boolean types | |
}; | |
template<op_nullary> | |
struct val_nullary | |
; | |
template<> | |
struct val_nullary<op_bool> | |
{ | |
static op_nullary const op_tag=op_bool; | |
typedef bool result_type; | |
result_type my_value; | |
val_nullary(result_type a_value) | |
: my_value(a_value) | |
{} | |
result_type value()const | |
{ | |
return my_value; | |
} | |
result_type operator!()const | |
{ | |
return !my_value; | |
} | |
operator bool()const | |
{ | |
return my_value; | |
} | |
template | |
< typename Access | |
> | |
auto | |
operator()(Access access)const | |
/**@brief | |
* Provide same interface that the op_ator_rands result provides. | |
*/ | |
{ | |
return access(*this); | |
} | |
}; | |
bool | |
operation_tagged(val_nullary<op_bool> op_v) | |
{ | |
std::cout<<"operation_tagged(val_nullary<op_bool>)\n"; | |
return op_v.value(); | |
} | |
val_nullary<op_bool> const | |
true_(true); | |
val_nullary<op_bool> const | |
false_(false); | |
template | |
< typename Op_T | |
, typename... Operands | |
> | |
typename Op_T::result_type | |
operation_tagged(Op_T op_v, Operands... operands) | |
; | |
auto operation_apply | |
= [](auto xs) | |
{ | |
return xs | |
( [](auto op_v, auto... operands) | |
{ | |
return operation_tagged(op_v, operands...); | |
} | |
); | |
}; | |
template | |
< typename Operand0 | |
, typename... Operands | |
> | |
bool | |
operation_tagged | |
( op_t<op_or> op_v | |
, Operand0 operand0 | |
, Operands... operands | |
) | |
{ | |
std::cout<<"op_or, operand0, operands...\n"; | |
bool result0=operation_apply(operand0); | |
if(result0) | |
return true; | |
else | |
return operation_tagged(op_v, operands...); | |
} | |
bool | |
operation_tagged(op_t<op_or> op_v) | |
{ | |
std::cout<<"op_or, Nullary \n"; | |
return false; | |
} | |
template | |
< typename Left | |
, typename Right | |
> | |
auto | |
operator|| | |
( Left left | |
, Right right | |
) | |
{ | |
return op_ator_rands(op_t<op_or>(),left,right); | |
} | |
template | |
< typename Operand0 | |
, typename... Operands | |
> | |
bool | |
operation_tagged | |
( op_t<op_and> op_v | |
, Operand0 operand0 | |
, Operands... operands | |
) | |
{ | |
std::cout<<"op_and, operand0, operands...\n"; | |
bool result0=operation_apply(operand0); | |
if(!result0) | |
return false; | |
else | |
return operation_tagged(op_v, operands...); | |
} | |
bool | |
operation_tagged(op_t<op_and> op_v) | |
{ | |
std::cout<<"op_and, Nullary \n"; | |
return true; | |
} | |
template | |
< typename Left | |
, typename Right | |
> | |
auto | |
operator&& | |
( Left left | |
, Right right | |
) | |
{ | |
return op_ator_rands(op_t<op_and>(),left,right); | |
} | |
int main() | |
{ | |
std::cout<<"false_="<<operation_apply(false_)<<"\n"; | |
std::cout<<"true_="<<operation_apply(true_)<<"\n"; | |
std::cout<<"***or_all_true_test.\n"; | |
auto or_all_true_input=true_||true_||true_; | |
auto or_all_true_output=operation_apply(or_all_true_input); | |
std::cout<<"or_all_true_output="<<or_all_true_output<<"\n"; | |
std::cout<<"***or_one_false_test.\n"; | |
auto or_one_false_input=true_||false_||true_; | |
auto or_one_false_output=operation_apply(or_one_false_input); | |
std::cout<<"or_one_false_output="<<or_one_false_output<<"\n"; | |
std::cout<<"***or_all_false_test.\n"; | |
auto or_all_false_input=false_||false_||false_; | |
auto or_all_false_output=operation_apply(or_all_false_input); | |
std::cout<<"or_all_false_output="<<or_all_false_output<<"\n"; | |
std::cout<<"***and_all_true_test.\n"; | |
auto and_all_true_input=true_&&true_&&true_; | |
auto and_all_true_output=operation_apply(and_all_true_input); | |
std::cout<<"and_all_true_output="<<and_all_true_output<<"\n"; | |
std::cout<<"***and_one_false_test.\n"; | |
auto and_one_false_input=true_&&false_&&true_; | |
auto and_one_false_output=operation_apply(and_one_false_input); | |
std::cout<<"and_one_false_output="<<and_one_false_output<<"\n"; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment