$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] Ternary logic programming (was: Re: [variant] Maintainer)
From: Lee Clagett (forum_at_[hidden])
Date: 2015-07-01 21:35:24
On Wed, Jul 1, 2015 at 8:49 PM, Niall Douglas <s_sourceforge_at_[hidden]>
wrote:
> On 1 Jul 2015 at 15:53, charleyb123 . wrote:
>
> > Under an alternative model, the common construct would be something like:
> >
> > void foo(...) {
> > return switch_(...) {
> > ...
> > }
> > }
> >
> > ... and you manage your true/false/unknown cases explicitly. Works great
> > for asynchronous and distributed, and for interfacing-with-hardware.
>
> That's exactly what Rust does. In fact, you'll find yourself either
> writing match x { patterns ... } or using monadic programming. A lot,
> because there is little other choice.
>
> Out of interest, what do you think of my free function ternary logic
> programming:
>
> tribool t;
> if(true_(t)) { /* true */ }
> else if(false_(t)) { /* false */ }
> else if(unknown(t)) { /* other state */ }
>
> Nobody here seemed to like it. I am looking for something the average
> programmer will notice immediately and not accidentally assume it's
> boolen logic going on here.
>
What if you combined a c++11 enum class with an implicit conversion
operator? The implicit conversion can take place in a switch statement, but
not if() or int() expressions since the enum class is not implicitly
convertible to those types.
enum class status { complete, error, waiting };
class niall_monad {
public:
constexpr niall_monad(const niall_monad&) = default;
constexpr niall_monad(status result) : result_(result) {}
constexpr operator status() const {
return result_;
}
private:
status result_;
};
constexpr bool is_complete(const niall_monad value) {
switch(value) {
case status::complete:
return true;
default:
case status::error:
case status::waiting:
return false;
}
}
int main() {
static_assert(!is_complete(niall_monad(status::waiting)), "");
static_assert(!is_complete(niall_monad(status::error)), "");
static_assert(is_complete(niall_monad(status::complete)), "");
if (niall_monad(status::complete)) { // fails
return 1;
}
int foo = niall_monad(status::complete); // fails
return 0;
}
With errors:
niall.cpp:33:7: error: no viable conversion from 'niall_monad' to 'bool'
if (niall_monad(status::complete)) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
niall.cpp:9:13: note: candidate function
constexpr operator status() const {
^
niall.cpp:37:7: error: no viable conversion from 'niall_monad' to 'int'
int foo = niall_monad(status::complete);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
niall.cpp:9:13: note: candidate function
constexpr operator status() const {
^
2 errors generated.
Remove the bad conversions, and you've got a compiled program. Are there
other situations that an enum class can implicit convert to something else?
A static case will force things obviously. I'd have to read the specs to
know.
Lee