Skip to content

Instantly share code, notes, and snippets.

@cppljevans
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cppljevans/01e23df914916ea7d16e to your computer and use it in GitHub Desktop.
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"
//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