Comparisons and sorting of a numeric class....
steve at pearwood.info
Thu Jan 15 09:41:47 CET 2015
On Wed, 14 Jan 2015 23:23:54 -0800, Andrew Robinson wrote:
> A subclass is generally backward compatible in any event -- as it is
> built upon a class, so that one can almost always revert to the base
> class's meaning when desired -- but subclassing allows extended meanings
> to be carried. eg: A subclass of bool is a bool -- but it can be MORE
> than a bool in many ways.
You don't have to explain the benefits of subclassing here.
I'm still trying to understand why you think you *need* to use a bool
subclass. I can think of multiple alternatives:
- don't use True and False at all, create your own multi-valued
truth values ReallyTrue, MaybeTrue, SittingOnTheFence, ProbablyFalse,
CertainlyFalse (or whatever names you choose to give them);
- use delegation to proxy True and False;
- write a class to handle the PossiblyTrue and PossiblyFalse cases,
and use True and False for the True and False cases;
There may be other alternatives, but what problem are you solving that
class MyBool(bool): ...
is the only solution?
> One example: It can also be a union.
I don't understand what you think this means. I know what *I* think it
means, but "subclass = union" doesn't make sense to me, so wonder what
you think it means.
> So when Guido chose to cut off
> subclassing -- his decision had a wider impact than just the one he
> mentioned; eg: extra *instances* of True and False.... as if he were
> trying to save memory or something.
*shrug* well maybe he was.
> The reason Guido's action puzzles me is twofold -- first it has been
> standard industry practice to subclass singleton (or n-ton) objects to
> expand their meaning in new contexts,
I dispute that. I *strongly* dispute that.
Industry practice, in my experience, is that there is one and only one
case where you can subclass singleton classes: when you have a factory
which chooses at runtime which subclass to instantiate, after which you
can no longer instantiate any of the other subclasses.
E.g. given an *abstract* class Maze, and three *concrete* subclasses
Labyrinth, OrdinaryMaze, and EnchantedMaze, you can have a factory
function, or method on Maze:
_the_instance = None
def create(cls, variant='ordinary'):
if cls._the_instance is None:
# Create the Maze singleton
if variant == 'ordinary':
cls._the_instance = OrdinaryMaze()
elif variant == 'labyrinth':
cls._the_instance = Labyrinth()
elif variant == 'enchanted':
cls._the_instance = EnchantedMaze()
(This is just a sketch of a solution, because the caller can bypass the
factory and just call the subclasses directly. In Java it is possible to
write this in such a way that the caller cannot easily do so.)
Why are we limited to a single Maze? Making Maze a singleton in the first
place was a bad idea. The singleton design pattern is *highly* over-used
and abused. But that is another story. Let's just assume that the
designer has good reason to insist that there be only one Maze, perhaps
it uses some resource which truly is limited to there being one only. If
that is the case, then allowing the caller to break that invariant by
subclassing will just lead to horrible bugs. By using a factory and
controlling access to the subclasses, Maze can keep the singleton
invariant and allow subclasses.
This is not relevant to bool, since True and False are already
> In general -- it's not the goal of subclassing to create more instances
> of the base types
That might not be the goal, but it is the effect. When you instantiate
the subclass, by definition the instances are also instances of the base
> -- but rather to refine meaning in a way that can be
> automatically reverted to the base class value (when appropriate) and to
> signal to users that the type can be passed to functions that require a
> bool because of backward compatibility.
And I am wondering what you think you can extend bools to perform that is
completely backwards compatible to code that requires bools?
I don't think you can. I think you are engaged on a fool's errand, trying
to do something impossible *even if subclassing bool were allowed*. But I
could be wrong. I just don't think you can possibly write code which is
backwards-compatible with code that expects bools while still extending
it. People are so prone to write:
if flag is True: ...
if flag is False: ...
(which is naughty of them, but what are you going to do?)
>> 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
> 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.
C doesn't have instances because it doesn't have objects. I'm not
certain, but I don't think the other languages you refer to are object-
oriented either. Verilog is a structured programming language, Silos is a
Verilog simulator, and I think VHDL and HDL are versions of Verilog (that
is, I've only seen them written as "Verilog-VHDL" and "Verilog-HDL").
In any case, Verilog *by design* uses four-state logic, modelling 1, 0,
floating, undefined. It is not a bool, since *by definition* bools model
only two states.
> The third value is usually called "TRI-state" or "don't care". (Though
> its sometimes a misnomer which means -- don't know, but do care.)
And SQL has NULL, which makes it an example of tri-state logic. (To be
precise, SQL uses a version of Kleene K3 logic.)
[snip description of modelling hardware circuits]
All very interesting, but completely irrelevant to the question of
> We've discovered that we live in a quantum-mechanical universe -- yet
> people still don't grasp the pragmatic issue that basic logic can be
> indeterminate at least some of the time ?!
Of course they do. My first post to you in this thread suggested that
before you start re-inventing the wheel you look at prior art in the
multi-value logic field.
> The name 'boolean logic' has never been re-named in honor of the many
> people who developed the advancements in computers -- including things
> like data sheets for electronic parts,
Are you really suggesting that the name of Boolean Logic should be
renamed away from the person who invented the field and instead named
after the person who first wrote down a list of electronic part numbers
and their specifications?
> or the code base used for solving
> large numbers of simultaneous logic equations with uncertainty included
> -- which have universally refined the boolean logic meanings found in
> "Truth" tables having clearly more than two values -- but don't take my
> word for it -- look in any digital electronics data book, and there they
> will be more than two states; marked with rising edges, falling edges,
> X's for don't cares, and so forth.
And those truth tables are not part of Boolean algebra.
> As I said to D'Aprano -- even a *cursory* examination (eg: as in not
> detailed) shows I could do things which he wasn't considering.
Andrew, I think you will be surprised at what I have considered. If you
search the archives, you will find that (by memory) a decade ago I had
considered using classes without instantiating them.
The questions I have about your strategy is not what can be done in
Python, but how you think these things you want to do will solve the
problem you apparently have?
To give an analogy... I have no doubt that you can build an television.
But I question how building a television solves your problem of
transporting a goat, a wolf and a cabbage across the river.
> I don't have a setting on my email to turn off html. Sorry. Can't help.
You are using Thunderbird. You certainly do have such a setting.
> I don't know what you mean about composition vs. sub-classing. Would you
> care to show an example of how it would solve the problem and still
> allow hierarchical sorting ?
Composition is just another name for delegation, which is often used as
the implementation of proxying. In an earlier message, you claimed to be
able to write proxies. Does that help?
> I don't see how you can get pre-existing python functions (like sort,
> max, and min) to accept a complex bool value and have that value
> automatically revert to a True or False in an intelligent manner without
> overloading the operators defined in some class -- somewhere -- to
> operate on the data the class contains.
Here, let me get you started on this:
def __new__(cls, value):
if value in (0, 1): return bool(value)
# Fold all other values to 2.
obj = super(TriStateLogic, cls).__new__(cls, 2)
And an example in use:
py> Undefined = TriStateLogic(999)
py> if Undefined:
... print "This is true"
... print "This is false"
This is false
py> sorted([True, False, Undefined, 99, 100])
[False, True, Undefined, 99, 100]
py> sorted([True, False, Undefined, 99, 100], reverse=True)
[100, 99, Undefined, True, False]
More information about the Python-list