sodiumfrp / sodium-cxx Goto Github PK
View Code? Open in Web Editor NEWSodium - Functional Reactive Programming (FRP) Library for C++
Sodium - Functional Reactive Programming (FRP) Library for C++
I was attempting to play with the library's stream<T>::map
method when I had this type
inference problem. Note that the problem can be reproduced with any of the library's
function/method that take std::function
as argument.
Some technical context: c++ - why do lambda functions in c++11 not have function<> types? - Stack Overflow.
Here's the method's definition I have on my side:
template <class A>
class stream /* ...*/ {
// ...
template <class B>
#if defined(SODIUM_NO_CXX11)
stream<B> map(const lambda1<B, const A&>& f) const {
#else
stream<B> map(const std::function<B(const A&)>& f) const {
#endif
transaction trans;
return stream<B>(impl::map_(trans.impl(), SODIUM_DETYPE_FUNCTION1(A,B,f), *this));
}
//...
};
At call site, I attempt to do the following:
stream<unit> myStream;
const stream<double> taggedStream = myStream.map([](const unit&) -> double { return 1.0; });
however, the compiler complains that:
no matching function for call to /home/ungava/dev/qt_sodium_experiment/main.cpp:38: error: no matching function for call to 'sodium::streamsodium::unit::map(main(int, char**)::<lambda(const sodium::unit&)>)'
Here are the three things I can do:
// Fallback #1
const std::function<double(const unit&)> f = [](const unit&) -> double { return 1.0; };
const stream<double> taggedStream = myStream.map(f);
// Fallback #2
const stream<double> taggedStream =
myStream.map<double>([](const unit&) -> double { return 1.0; });
// Fallback #3
const stream<double> taggedStream =
myStream.map(std::function<double(const unit&)>([](const unit&) -> double { return 1.0;
A bit too verbose to my taste.
I decided to attempt to define a simple non member template function taking
a arbitrary unary function like argument in a C++03 compatible way:
template <typename A, typename FnT>
stream<typename std::result_of<FnT(A)>::type> mapStream(const stream<A>& self, FnT fn)
{
typedef typename std::result_of<FnT(A)>::type B;
return self.map(std::function<B(const A&)>(fn));
}
And now, the following call site becomes much less verbose:
stream<double> taggedStream = mapStream(myStream, [](const unit&) -> double { return 1.0; });
Wouldn't it be better to replace the whole method declaration / definition by:
template <class A>
class stream /* ...*/ {
// ...
template <typename FnT>
stream<typename std::result_of<FnT(A)>::type> map(FnT fn) {
typedef typename std::result_of<FnT(A)>::type B;
transaction trans;
const std::function<B(const A&)> f(fn);
return stream<B>(impl::map_(trans.impl(), SODIUM_DETYPE_FUNCTION1(A,B,f), *this));
}
//...
};
The same method will now work fine with any function like object (including std::function and
this lambda1
type), even simple non member functions.
Note that as boost already defines a result_of
type trait with same interface as
C++11, both C++03 and C++11 case can be covered (a sodium wrapper type trait
can be implemented in term of either).
Doing so for all primitive operations would to my impression make the C++11 version of
the library as enjoyable/easy to use as its java 8 counterpart.
Is it aligned on the version in other language at https://github.com/SodiumFRP/sodium/releases ?
This was fixed in the C# version. Make sure it's fixed in the C++ version.
SodiumFRP/sodium@fb73c43
I've translated "Gc.rs" from Rust to C++ . It is designed to work exactly the same way as the rust one. It uses the template struct Trace
to mimic a Trace
trait.
https://github.com/clinuxrulz/gc-cxx
If this is the sort of approach you would like to use, then maybe it could find a home in "SodiumFRP/.." somewhere.
The strategy in mind for use is: WeakGc<>
forward references, Gc<>
back references. The back references tend to get held in the cleanup/finalizers of the sodium objects.
Trace
implementations would need to be provided for Cell/Stream and Listener to use it. (I.E. Anywhere a Gc<>
could be held needs to be made reachable by Trace<>::trace(...)
)
Here is what it looks like when you use it:
https://github.com/clinuxrulz/gc-cxx/blob/master/example.cpp
The example creates a cycle among 3 objects and shows them getting freed at the end of the local scope.
In file included from /nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/transaction.h:11:0,
from /nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/sodium.h:11,
from ../qt_sodium_experiment/main.cpp:12:
/nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/count_set.h:56:44: warning: unused parameter 'other' [-Wunused-parameter]
count_set(const count_set& other)
^
/nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/count_set.h:61:57: warning: unused parameter 'other' [-Wunused-parameter]
count_set& operator = (const count_set& other) { return *this; }
^
In file included from /nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/transaction.h:16:0,
from /nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/sodium.h:11,
from ../qt_sodium_experiment/main.cpp:12:
/nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/unit.h:16:39: warning: unused parameter 'other' [-Wunused-parameter]
bool operator == (const unit& other) const { return true; }
^
/nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/unit.h:17:39: warning: unused parameter 'other' [-Wunused-parameter]
bool operator != (const unit& other) const { return false; }
^
In file included from /nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/sodium.h:11:0,
from ../qt_sodium_experiment/main.cpp:12:
/nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/transaction.h:131:28: warning: unused parameter 'other' [-Wunused-parameter]
mutex(const mutex& other) {}
^
/nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/transaction.h:132:41: warning: unused parameter 'other' [-Wunused-parameter]
mutex& operator = (const mutex& other) { return *this; }
^
/nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/transaction.h:416:46: warning: unused parameter 'other' [-Wunused-parameter]
transaction_(const transaction_& other) {}
^
/nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/transaction.h:417:59: warning: unused parameter 'other' [-Wunused-parameter]
transaction_& operator = (const transaction_& other) { return *this; };
^
/nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/transaction.h:431:44: warning: unused parameter 'other' [-Wunused-parameter]
transaction(const transaction& other) : impl::transaction_(def_part::part()) {}
^
/nix/store/4545f4v6w7hhsc1s8mqjj5wi3h9va837-ungava-build-desktop-env/include/sodium/transaction.h:433:57: warning: unused parameter 'other' [-Wunused-parameter]
transaction& operator = (const transaction& other) { return *this; };
Most could be easily fixed by simply removing the variable name.
Using gcc 4.9.3, compiling version 720acee.
As discussed in SodiumFRP/sodium#106, we should add a Transaction.isActive() method that returns true if we are currently within a transaction. This is useful for integration into non-FRP GUI libraries.
I believe this line should be changed from:
else {
to:
else if (l->colour != colour_t::gray) {
I believe it is an actual mistake made in the bacon Rajan gc paper itself.
Otherwise the next root being processed can damage the work done by mark_gray()
This bug needs to be fixed in the C++ version. See SodiumFRP/sodium#124
I'm navigating the code and it seems in the presence of C++11, the principal need for
boost is to draw its optional
class and a secondary need seems to be for its
intrusive_ptr
class.
It seems to me it wouldn't be too hard to introduce a simple drop-in replacement for
both, thus making this library self-contained.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.