On Friday, January 23, 2015 at 5:18:32 PM UTC+5:30, Andrew Robinson wrote: > On 01/15/2015 09:05 AM, Ian Kelly wrote: > > On Thu, Jan 15, 2015 at 12:23 AM, Andrew Robinson wrote: > >> Can you name any other language that *does* allow subclassing of > >> booleans or creation of new boolean values? > >> > >> Yes. Several off the top of my head -- and I have mentioned these before. > >> They generally come with the extra subclasses pre-created and the user > >> doesn't get to create the classes, but only use them; none the less -- they > >> have more than two values with which to do logic equations with. > >> > >> VHDL, Verilog, HDL, Silos III, and there are IEEE variants also. > >> C/C++ historically allowed you to do it with instances included, although I > >> am not sure it still does. > > Sorry, let me rehprase my question. Of course there will be > > special-purpose languages that allow you to do interesting things with > > the logic values and operators. Can you name any other > > *general-purpose* language that allows subclassing of booleans or > > creation of new boolean values? If not, it seems rather unfair to > > single out Python and marvel that this isn't allowed when it's > > actually quite normal to disallow it. Unless you care to provide an > > example, I am fairly sure your claim of C/C++ is wrong. The bool type > > in C++ is a primitive type, none of which can be inherited from. C > > doesn't even have a bool type; at most you have macros for true and > > false to 1 and 0, so the "booleans" there are just ordinary integers. > Ian, > I agree with you mostly; there is good reason to pick on other > languages, too, with respect to what a bool is. > > Although, I have to laugh -- Verilog can syntheze a CPU -- implement > memory -- and then load a program and run python on the virtual > machine. When the pentium was first developed, I watched as Intel > actually booted up MS-DOS under using Xilinx chips to run the verilog > program's output they could physically run anything a pentium processor > could run. That's *IS* what I consider "general purpose". > > But you're sort of confounding my need for type information in my new > class as a way to advertise compatability with bool, with subclassing -- > which is only one way that I was exploring to get the 'type' name > attached to the new object; That's a mistake that D'Aprano seems to be > repetitively making as well. > But please note: Type checking for 'bool' is only needed for > legacy/compatability reasons -- but new code can use any type; so > subtyping is not strictly necessary if there is another way to get the > 'bool' type attached to my return object for advertising purposes; for > what I am interested in is an object who presents as bool for legacy > code, but new code can convert it to anything at all.. > > C++ *DOES* allow the necessary kind of type checking and subclassing for > what I need to do in spite of not having a subclass mechanism built into > the language for base types; eg: C++ allows a semantic subclass to be > constructed which can be typecast to a bool for compatibility, but > otherwise presents extra data and the type the enhanced object reports > is irrelevant. As I've mentioned before, people can do object oriented > programming in C, So, to satisfy your curiosity -- I'll show you a > mixed C/C++ example, where I make a semantic subclass that has five > values AllFalse, PartFalse, Uncertain, PartTrue, True ; and these five > values will have a typeid() of bool and be 100% compatible with legacy > C++ bool; but upon request, they these 'bool' types will re-cast into a > semantic subtype that provides additional certainty data. > > See the program at end of e-mail. It compiles with gcc 4.8.2 with no > warnings; g++ filename.cc ; ./a.out > > But let me explain a bit more why I'm picking on Python: For even if we > set the electronic engineering concerns aside that I've raised (and they > are valid, as OOP is supposed to model reality, not reality be bent to > match OOP) -- People's facile explanations about why Python's version of > bool is the way it is -- still bothers me here in the python mail list > -- because people seem to have a very wrong idea about bool's nature as > a dualton being somehow justified solely by the fact that there are only > two values in Boolean logic; For, singletons style programming is not > justified by the number of values an object has in reality -- And I know > Charles bool didn't use singletons in his algebra, -- just read his > work and you'll see he never mentions them or describes them, but he > does actually use dozens of *instances* of the True and False objects he > was talking about -- for the obvious reason that he would have needed > special mirrors, dichroic or partially silvered, to be even able to > attempt to make one instance of True written on paper show up in > multiple places; And that's silly to do when there's no compelling > reason to do it. > > Yet -- people here seem to want to insist that the bool type with only > two *instances* is some kind of pure re-creation of what Charles Bool > did -- when clearly it isn't. It's a amalgamation of enhancements such > as binary words instead of just True/False and many other things > (operators that work on words rather than single bits.). So -- I don't > see that Python's implementation of Bool is justified by either a purist > appeal to Charles bool, or by ignoring pragmatic concerns that have been > attached to Bool's work for years by Electrical Engineers in order to > make it more useful for *practical* computer problems. Yet these two > things are what this python list has sort of harped on. > > That brings me to your point about other languages; I think following > other languages restrictions arbitrarily is potentially a lemmings > approach, eg: just because 'everyone' is doing it statistically does not > mean that it is good to do it that way; If many languages do something, > there is excellent cause to examine and look for reasons 'why' they do > that (and I'd love to hear your opinions) but Python has a different set > of constraints as an interpreter, as opposed to a compiler, and many > other differences which cause unintended side effects when mimicking > other programming languages. It's the unintended side effects and > surprises when a hasty decision is made that's the issue here. > > Where python is different from other languages regarding bool -- and > deserves a little extra picking on, is that Guido has imposed four > constraints *simultaneously* to bool which together cause a conflict > that I don't think (offhand) I've ever encountered in another language; > Definitely not in C/C++! > > The four things are: 1 -- he cut off subtyping and created no alternate > method of doing type checking of duck-types, 2 -- he does not allow > multiple instances, 3 -- he himself did not implement bool using the > standard alternative methodology to subclassing -- eg: as a composite > structure with delegation. 4. and he has made bool into the default > return type for base type comparison operators; which means that general > programmers expect a bool for base types and may check for it, even if > Python's built in functions do not. > > If any one of these four things had not been done, I would not have > reason to complain about bool in Python; because there would be a way > for me to easily work with people expecting a bool as a return type from > comparison operators, using standard OOP techniques and a little > creativity to make something perfectly compatible; rather than having to > dig through manuals endlessly with conflicting notions, pep's, and > subtleties that make for an extremely steep learning curve and lots of > time spent making only slight progress when there's not much *reasoning* > behind what Guido did which is consistent and useable as a guideline... > > As far a subtyping goes; The very fact that Guido used subtyping to > create bool in the first place (subtype of int), precludes any real > claim that bool should not itself be subclassable just because bools > only have two values; I mean, seriously -- Guido's 'strict' Bool is > already an impure form of OOP that is borderline hypocrisy, as it can > '+' to 2 or 3... and many other things; and worse I've just come across > a couple of papers which suggest that Guido doesn't like subclassing > when Composite object structures could be used instead to replace the > subclass 'is' relationship with a 'has a' relationship. So -- if that's > the case, why isn't bool a composite to begin with ? eg: Guido's > programming guides must be read with a caveat 'do what Guido says and > not what Guido does' ?! > > Now to your last point -- I need to point out that C++ does not have > all four restrictions I've mentioned so it doesn't have the problem > Python does; In C++, there are instances of bool, and therefore I can > easily encode extra information in a bool object without changing the > object itself. > > Here's a skeleton example, where I only implement one operator '<' on > the semantic subclass, but the example shows the principle of how to > extend the bool type via typecasting to bool. There are better ways of > doing this, and there are some problems with how I implemented esp. as > many use cases are not properly covered -- but it serves to show that > C/C++ CAN encode new subtypes (semantic subtypes only not C++ subtypes) > while using only the base type itself to transmit data in a perfectly > backwards compatible way. In Python, however, it's pretty close to > hopeless... > > #include <iostream> > #include <typeinfo> > using namespace std; > > // Create a new super-bool type which is semantically a subtype of bool, > // But have it masquerade as a bool for compatability, unless new code > // explicity typecasts it and access its subtype members. > > struct _SBool { > bool basebool; > int certainty; > }; > > class SBool: public _SBool { > public: > SBool( const bool& ); > bool operator < (const SBool &); > }; > > // Create all 4 of the statistical uncertainty values as penta-ton. > const _SBool bools[5] = {{false,0},{false,1},{false,2},{false,3},{true,4}}; > > // Create 4 global alias bool names having full compatability with bool > // for legacy code, but useable in mixed or advanced compares. > > const bool & AllFalse = bools[0].basebool; // uncertainty 0 > const bool & PartFalse = bools[1].basebool; // uncertainty 1 > const bool & Uncertain = bools[2].basebool; // uncertainty 2 > const bool & PartTrue = bools[3].basebool; // uncertainty 3 > const bool & True = bools[4].basebool; // uncertainty 4 > > // Create the typecast method. > SBool::SBool( const bool &b ) { > const void* that = &b; > if ((that >= bools) && (that < bools+5)) *this=*(const SBool*)that; > else *this=*(const SBool*)(const void*) &(b?True:AllFalse); > > bool SBool::operator < (const SBool &other ) { > return this->certainty < other.certainty; > } > > // ------------------------------------ Test harness. > int main(void) { > cout << "type match=" << (typeid(bool) == typeid(AllFalse)) << endl; > cout << "testing as bool " << AllFalse << PartFalse << > Uncertain << PartTrue << True << endl; > cout << "testing as SBool " << SBool(PartFalse).certainty << > endl; > cout << "testing up-cast false " << SBool(false).certainty << endl; > cout << "testing up-cast true " << SBool(true).certainty << endl; > cout << "testing advanced compare (should be true)" << > (SBool(AllFalse) < PartFalse) << endl; > cout << "testing legacy compare (should be false) " << (AllFalse < > PartFalse) << endl; > return 0; > } > > //------------------------------------ End of program, Test output > follows ------------------- > > type match=1 > testing as bool 00001 > testing as SBool 1 > testing up-cast false 0 > testing up-cast true 4 > testing advanced compare (should be true)1 > testing legacy compare (should be false) 0bash-4.2$
Can you tell me what of the following code does not satisfy your requirements? [Needs python 3.4] >>> from enum import IntEnum >>> class B4(IntEnum): F1 = 0 F2 = 0 F3 = 0 T = 1 In words: Thats a type of 4-valued boolean Of which F1/2/3 behave falsey in standard python bool-expecting contexts T behaves truey (or truish) [Check with bool(B4.F1) for example] If you get fed up with typing B4.blah make global variables (actually constants) F2 = B4.F2 If you need to distinguish the falsey ones, its a bit of a headache dict(B4.__members__) should contain all the info you need to make these distinctions -- https://mail.python.org/mailman/listinfo/python-list