Replies: 2 comments 2 replies
-
You can have 2-input joining with namespace usingstdcpp2019::urp{
namespace detail{
template<typename T,typename U>
struct function_pair
{
template<typename F>
auto operator|(F f)&&
{
return urp::function{f,std::forward<T>(x),std::forward<U>(y)};
}
T x;
U y;
};
} /* namespace detail */
template<
typename T,typename U,
std::enable_if_t<detail::is_function_or_value<T>>* =nullptr,
std::enable_if_t<detail::is_function_or_value<U>>* =nullptr
>
detail::function_pair<T&&,U&&> operator,(T&& x,U&& y)
{
return {std::forward<T>(x),std::forward<U>(y)};
}
} /* namespace usingstdcpp2019::urp */
#include <iostream>
int main()
{
using namespace usingstdcpp2019;
auto times3=[](auto x){return 3*x;};
auto mult=[](auto x,auto y){return x*y;};
urp::value x=0,y=0;
urp::function z=(x,y|times3)|mult;
x=2;
y=3;
std::cout<<z.get()<<"\n"; // prints 18
} |
Beta Was this translation helpful? Give feedback.
2 replies
-
So, after a set of interface changes ureact become a little more beautiful.
Now, ureact looks more like urp. ureact::context ctx;
ureact::var_signal<int> b = ctx.make_var( 1 );
ureact::var_signal<int> c = ctx.make_var( 2 );
ureact::signal<int> a = b + c;
CHECK( a.value() == 3 );
b <<= 10;
CHECK( a.value() == 12 ); => ureact::context ctx;
ureact::value<int> b = ctx.make_value( 1 );
ureact::value<int> c = ctx.make_value( 2 );
ureact::function<int> a = b + c;
CHECK( a.get() == 3 );
b <<= 10;
CHECK( a.get() == 12 ); Optionally if we use c++17, the type can be omited: ureact::value b = ctx.make_value( 1 );
ureact::value c = ctx.make_value( 2 );
ureact::function a = b + c; But context is still required, so need to perform some more changes to achieve following sintax: ureact::value b = 1;
ureact::value c = 2;
ureact::function a = b + c; |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Current names for classes are:
They are more or less the same as in the original c++react.
In the urp I've seen a way more expressive and elegant naming:
There are no context and observer class analogues in urp.
observable:
Also, I've seen another expressive name for event_source -- emitter.
Naming and syntax sugar is very important to make usage of the library pleasant and intuitive.
Let's compare hello world examples from different libraries:
ureact:
c++react
observable
urp:
urp is definitely a winner here (with some cheating of using c++17 features).
To achieve the same way of coolness first of all need to make some kind of default context and make c++17 example:
Then need naming change. For example like this:
I personally like <<= operator because it definitely says that there is something unusual happening here. This is not a free operation.
Namespace ureact is quite verbose at my taste, 3 letters long names are better (std, fmt, urp), but it is not a big problem in general.
Another beautiful masterpiece that worth borrowing from urp is a function piping.
Ureact has inherited operator ->* from c++react, but it is way less expressive:
But it is definitely more universal because allows the joining of 2 inputs into a single function:
Changing operator ->* is definitely worth it.
Beta Was this translation helpful? Give feedback.
All reactions