473,776 Members | 1,498 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Proto-PEP: Overloadable Boolean Operators

Discussion is invited on the following proto-PEP.

-------------------------------------------------------------

PEP ??? - Overloadable Boolean Operators
=============== =============== ==========

SUMMARY

This PEP proposes an extension to permit objects to define their own
meanings for the boolean operators 'and', 'or' and 'not', and suggests
an efficient strategy for implementation. A prototype of this
implementation is available for download from:

http://www.cosc.canterbury.ac.nz/~gr...hon_OBO.tar.gz
BACKGROUND

Python does not currently provide any '__xxx__' special methods
corresponding to the 'and', 'or' and 'not' boolean operators. In the
case of 'and' and 'or', the most likely reason is that these operators
have short-circuiting semantics, i.e. the second operand is not
evaluated if the result can be determined from the first operand. The
usual techique of providing special methods for these operators
therefore would not work.

There is no such difficulty in the case of 'not', however, and it
would be straightforward to provide a special method for this
operator. The rest of this proposal will therefore concentrate on
providing a way to overload 'and' and 'or'.

MOTIVATION

There are many applications in which it is natural to provide custom
meanings for Python operators, and in some of these, having boolean
operators excluded from those able to be customised can be
inconvenient. Examples include:

1. Numeric/Numarray, in which almost all the operators are defined on
arrays so as to perform the appropriate operation between
corresponding elements, and return an array of the results. For
consistency, one would expect a boolean operation between two arrays
to return an array of booleans, but this is not currently possible.

There is a precedent for an extension of this kind: comparison
operators were originally restricted to returning boolean results, and
rich comparisons were added so that comparisons of Numeric arrays
could return arrays of booleans.

2. A symbolic algebra system, in which a Python expression is
evaluated in an environment which results in it constructing a tree of
objects corresponding to the structure of the expression.

3. A relational database interface, in which a Python expression is
used to construct an SQL query.

A workaround often suggested is to use the bitwise operators '&', '|'
and '~' in place of 'and', 'or' and 'not', but this has some
drawbacks. The precedence of these is different in relation to the
other operators, and they may already be in use for other purposes (as
in example 1). There is also the aesthetic consideration of forcing
users to use something other than the most obvious syntax for what
they are trying to express. This would be particularly acute in the
case of example 3, considering that boolean operations are a staple of
SQL queries.

REQUIREMENTS

The requirements for a successful solution to the problem of allowing
boolean operators to be customised are:

1. In the default case (where there is no customisation), the existing
short-circuiting semantics must be preserved.

2. There must not be any appreciable loss of speed in the default
case.

3. If possible, the customisation mechanism should allow the object to
provide either short-circuiting or non-short-circuiting semantics, at
its discretion.

One obvious strategy, that has been previously suggested, is to pass
into the special method the first argument and a function for
evaluating the second argument. This would satisfy requirements 1 and
3, but not requirement 2, since it would incur the overhead of
constructing a function object and possibly a Python function call on
every boolean operation. Therefore, it will not be considered further
here.

The following section proposes an implementation that addresses all
three requirements. A prototype of this implementation, in the form of
a patch to Python 2.3, is available from:

http://www.cosc.canterbury.ac.nz/~gr...hon_OBO.tar.gz
PROPOSAL

Special Methods

At the Python level, objects may define the following special methods.

Unary: __not__(self)

Binary, phase 1: __and1__(self) __or1__(self)

Binary, phase 2: __and2__(self, other) __or2__(self, other)
__rand2__(self, other) __ror2__(self, other)

The __not__ method, if defined, implements the 'not' operator. If it
is not defined, or it returns NotImplemented, existing semantics are
used.

To permit short-circuiting, processing of the 'and' and 'or' operators
is split into two phases. Phase 1 occurs after evaluation of the first
operand but before the second. If the first operand defines the
appropriate phase 1 method, it is called with the first operand as
argument. If that method can determine the result without needing the
second operand, it returns the result, and further processing is
skipped.

If the phase 1 method determines that the second operand is needed, it
returns the special value NeedOtherOperan d. This triggers the
evaluation of the second operand, and the calling of an appropriate
phase 2 method.

Processing falls back to existing semantics if at any stage a relevant
special method is not found or returns NotImplemented.

As a special case, if the first operand defines a phase 2 method but
no corresponding phase 1 method, the second operand is always
evaluated and the phase 2 method called. This allows an object which
does not want short-circuiting semantics to simply implement the
relevant phase 2 methods and ignore phase 1.
Bytecodes

The patch adds four new bytecodes, LOGICAL_AND_1, LOGICAL_AND_2,
LOGICAL_OR_1 and LOGICAL_OR_2. As an example of their use, the
bytecode generated for an 'and' expression looks like this:

Jul 18 '05
14 2529
On Tue, 07 Sep 2004 16:37:18 +1200, Greg Ewing
<gr**@cosc.cant erbury.ac.nz> wrote:
Alex Martelli wrote:
Problem is, __nonzero__ is currently
typechecked -- it has to return an integer.


Yes, that's the problem. I should probably elaborate
on that a bit in the PEP.


That is not the only issue with __nonzero__ versus __not__ -- in some
cases (e.g. the symbolic algebra or SQL query constructor) it is
useful to determine when an explicit "not" operator has been used.

I'm not at a machine with the patch installed on it at the moment, but
I just began to whether this patch would have an effect on expressions
like (a < b < c) (which are also short-circuiting)... Come to think
of it, how do objects which override __gt__ and the other comparisons
(particularly for expression construction) work in that case?
Jul 18 '05 #11
Andrew Durdin <ad*****@gmail. com> wrote:
On Tue, 07 Sep 2004 16:37:18 +1200, Greg Ewing
<gr**@cosc.cant erbury.ac.nz> wrote:
Alex Martelli wrote:
Problem is, __nonzero__ is currently
typechecked -- it has to return an integer.
Yes, that's the problem. I should probably elaborate
on that a bit in the PEP.


That is not the only issue with __nonzero__ versus __not__ -- in some
cases (e.g. the symbolic algebra or SQL query constructor) it is
useful to determine when an explicit "not" operator has been used.


Yes, you're right, and my assertion was flawed. Typechecking is only
part of the issue.

I'm not at a machine with the patch installed on it at the moment, but
I just began to whether this patch would have an effect on expressions
like (a < b < c) (which are also short-circuiting)... Come to think
of it, how do objects which override __gt__ and the other comparisons
(particularly for expression construction) work in that case?


I believe a < b < c has exactly the semantics of [but with no doube
evaluation of b...]:
(a < b) and (b < c)

Overriding _lt_ to give a print seems to confirm that:

In [1]: class chatty:
...: def __init__(self, i): self.i = i
...: def __lt__(self, other):
...: print '%d < %d' % (self.i, other.i)
...: return self.i < other.i
...:

In [2]: chatty(3) < chatty(6) < chatty(9)
3 < 6
6 < 9
Out[2]: True

In [3]: chatty(3) < chatty(16) < chatty(9)
3 < 16
16 < 9
Out[3]: False

In [4]: chatty(3) < chatty(1) < chatty(9)
3 < 1
Out[4]: False
Alex
Jul 18 '05 #12
al*****@yahoo.c om (Alex Martelli) writes:
Andrew Durdin <ad*****@gmail. com> wrote:
On Tue, 07 Sep 2004 16:37:18 +1200, Greg Ewing
<gr**@cosc.cant erbury.ac.nz> wrote:
Alex Martelli wrote:
> Problem is, __nonzero__ is currently
> typechecked -- it has to return an integer.

Yes, that's the problem. I should probably elaborate
on that a bit in the PEP.


That is not the only issue with __nonzero__ versus __not__ -- in some
cases (e.g. the symbolic algebra or SQL query constructor) it is
useful to determine when an explicit "not" operator has been used.


Yes, you're right, and my assertion was flawed. Typechecking is only
part of the issue.

I'm not at a machine with the patch installed on it at the moment, but
I just began to whether this patch would have an effect on expressions
like (a < b < c) (which are also short-circuiting)... Come to think
of it, how do objects which override __gt__ and the other comparisons
(particularly for expression construction) work in that case?


I believe a < b < c has exactly the semantics of [but with no doube
evaluation of b...]:
(a < b) and (b < c)

Overriding _lt_ to give a print seems to confirm that:


dis.dis can be used to give the same impression:
def f(a, b, c): .... return a < b < c
.... def g(a, b, c): .... return a < b and b < c
.... dis.dis(f) 2 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (b)
6 DUP_TOP
7 ROT_THREE
8 COMPARE_OP 0 (<)
11 JUMP_IF_FALSE 10 (to 24)
14 POP_TOP
15 LOAD_FAST 2 (c)
18 COMPARE_OP 0 (<)
21 JUMP_FORWARD 2 (to 26)
24 ROT_TWO 25 POP_TOP 26 RETURN_VALUE 27 LOAD_CONST 0 (None)
30 RETURN_VALUE dis.dis(g)

2 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (b)
6 COMPARE_OP 0 (<)
9 JUMP_IF_FALSE 10 (to 22)
12 POP_TOP
13 LOAD_FAST 1 (b)
16 LOAD_FAST 2 (c)
19 COMPARE_OP 0 (<) 22 RETURN_VALUE

23 LOAD_CONST 0 (None)
26 RETURN_VALUE

Cheers,
mwh

--
at any rate, I'm satisfied that not only do they know which end of
the pointy thing to hold, but where to poke it for maximum effect.
-- Eric The Read, asr, on google.com
Jul 18 '05 #13
Andrew Durdin wrote:
I'm not at a machine with the patch installed on it at the moment, but
I just began to whether this patch would have an effect on expressions
like (a < b < c)


No, it won't have any effect on those. I don't think
it should, either -- it should only apply when you
explicitly write an 'and'.

--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg

Jul 18 '05 #14
Greg Ewing wrote:
Andrew Durdin wrote:
I'm not at a machine with the patch installed on it at the moment, but
I just began to whether this patch would have an effect on expressions
like (a < b < c)

No, it won't have any effect on those. I don't think
it should, either -- it should only apply when you
explicitly write an 'and'.


[I should probably download the patch and try this before commenting,
but no time, so: open mouth, insert foot].

Why? You specifically mention Numeric/Numarray as one motivating factor
for this patch, and as a long time Numeric/Numarray user I'd rather have
(a < b < c) work than (a and b).

My biggest concern is that if (a < b < c) is not changed in conjunction
with (a and b), the behaviour of the former becomes difficult to
explain. Currently one can explain it by saying, "a < b < c is
interpreted as (a < b) and (b < c), and 'and' doesn't work on numeric
arrays". However, if 'and' starts to work sensible for numarrays, but (a
< b < c) retains the old behaviour, the behaviour becomes both hard to
explain and hard to understand.

I'll try to download the patch and comment more completely later.

-tim

Jul 18 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
3261
by: fedor | last post by:
Hi all, happy new year, I was trying to pickle a instance of a subclass of a tuple when I ran into a problem. Pickling doesn't work with HIGHEST_PROTOCOL. How should I rewrite my class so I can pickle it? Thanks , Fedor
10
3154
by: x2164 | last post by:
hi all, Linux 2.4.28 Glibc 2.2.5 gcc 2.95.3 I'm new to Python. I've compiled Python 2.4 from tar file.
3
2120
by: Earl Eiland | last post by:
I'm trying to process the IP packet length field, as recorded by pcap (Ethereal) and recovered using pcapy. When I slice out those bytes, I get a value that shows in '\x00' format, rather than '0x00'. Neither int() nor eval() are working. How do I handle this? Earl Eiland
35
3685
by: Troll | last post by:
Hi, I need to write a script which reads some data and reports the findings. Just to give you an idea the structure is similar to the following. Data input example: HEADING 1 ********** ColumnA ColumnB ColumnC ColumnD ColumnE
3
2527
by: Philippe Guglielmetti | last post by:
Look at these few lines of code: class A { public: virtual void f() { cout << "A";}}; class B : public A{public: static void f() { cout << "B"; }}; class C : public B{public: void f() { cout << "C"; }}; // virtual or not ? that's the question... int main(int, char**) { A* x; A a; B b; C c;
2
3896
by: Jackson Yap | last post by:
can someone kind enough to help me look at the attached html and js file? Why is it that the javascript menu could not work at www.apchosting.net but could work at http://home.pacific.net.sg/~jacksony ? (the drop down bar could not work at www.apchosting.net but can drop at home.pacific.net.sg. I suspect it is a server problem but was told it is not possible, therefore assuming it is a client script problem? the script works last time...
8
2036
by: Geoff Cox | last post by:
Hello, When using Internet Explorer, on networked PCs in a college, to view a page of mine with Javascript code in it the "stack overflow" error message appears. When I access the same file from my home PC no such message. Is it possible for this to be caused by any IE setting?
2
1375
by: ian | last post by:
Hi; What is void daily_log(char *, ...); saying, the 3 periods? Regards Ian
0
1223
by: Neil Cerutti | last post by:
I'm a royal n00b to writing translators, but you have to start someplace. In my Python project, I've decided that writing the dispatch code to sit between the Glulx virtual machine and the Glk API will be best done automatically, using the handy prototypes. Below is the prototype of the lexer, and I'd like some comments in case I'm doing something silly already.
2
1832
by: Hal Vaughan | last post by:
I have a file where I'm putting a lot of variable definitions. Some of them will be maps that include references to functions. This file will be processed (by include) before other files are processed. If I put protofunction definitions in this definition file and the actual functions in another file, are there any non-obvious consequences to this? Thanks! Hal
0
9628
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10289
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10061
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9923
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6722
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5367
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4031
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3622
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2860
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.