@@ -5,189 +5,198 @@ Last-Modified: $Date$
55Author: gvwilson@ddj.com (Greg Wilson)
66Status: Deferred
77Type: Standards Track
8+ Content-Type: text/x-rst
89Created: 15-Jul-2000
910Python-Version: 2.1
1011Post-History:
1112
1213
1314Introduction
15+ ============
1416
15- This PEP describes a proposal to define "@" (pronounced "across")
16- as a new outer product operator in Python 2.2. When applied to
17- sequences (or other iterable objects), this operator will combine
18- their iterators, so that:
17+ This PEP describes a proposal to define ``@`` (pronounced "across")
18+ as a new outer product operator in Python 2.2. When applied to
19+ sequences (or other iterable objects), this operator will combine
20+ their iterators, so that: :
1921
20- for (i, j) in S @ T:
21- pass
22+ for (i, j) in S @ T:
23+ pass
2224
23- will be equivalent to:
25+ will be equivalent to: :
2426
25- for i in S:
26- for j in T:
27- pass
27+ for i in S:
28+ for j in T:
29+ pass
2830
29- Classes will be able to overload this operator using the special
30- methods " __across__", " __racross__" , and " __iacross__" . In
31- particular, the new Numeric module (PEP 209) will overload this
32- operator for multi-dimensional arrays to implement matrix
33- multiplication.
31+ Classes will be able to overload this operator using the special
32+ methods `` __across__``, `` __racross__`` , and `` __iacross__`` . In
33+ particular, the new Numeric module (PEP 209) will overload this
34+ operator for multi-dimensional arrays to implement matrix
35+ multiplication.
3436
3537
3638Background
37-
38- Number-crunching is now just a small part of computing, but many
39- programmers --- including many Python users --- still need to
40- express complex mathematical operations in code. Most numerical
41- languages, such as APL, Fortran-90, MATLAB, IDL, and Mathematica,
42- therefore provide two forms of the common arithmetic operators.
43- One form works element-by-element, e.g. multiplies corresponding
44- elements of its matrix arguments. The other implements the
45- "mathematical" definition of that operation, e.g. performs
46- row-column matrix multiplication.
47-
48- Zhu and Lielens have proposed doubling up Python's operators in
49- this way [1]. Their proposal would create six new binary infix
50- operators, and six new in-place operators.
51-
52- The original version of this proposal was much more conservative.
53- The author consulted the developers of GNU Octave [2], an open
54- source clone of MATLAB. Its developers agreed that providing an
55- infix operator for matrix multiplication was important: numerical
56- programmers really do care whether they have to write "mmul(A,B)"
57- instead of "A op B".
58-
59- On the other hand, when asked how important it was to have infix
60- operators for matrix solution and other operations, Prof. James
61- Rawlings replied [3]:
62-
63- I DON'T think it's a must have, and I do a lot of matrix
64- inversion. I cannot remember if its A\b or b\A so I always
65- write inv(A)*b instead. I recommend dropping \.
66-
67- Based on this discussion, and feedback from students at the US
68- national laboratories and elsewhere, we recommended adding only
69- one new operator, for matrix multiplication, to Python.
39+ ==========
40+
41+ Number-crunching is now just a small part of computing, but many
42+ programmers --- including many Python users --- still need to
43+ express complex mathematical operations in code. Most numerical
44+ languages, such as APL, Fortran-90, MATLAB, IDL, and Mathematica,
45+ therefore provide two forms of the common arithmetic operators.
46+ One form works element-by-element, e.g. multiplies corresponding
47+ elements of its matrix arguments. The other implements the
48+ "mathematical" definition of that operation, e.g. performs
49+ row-column matrix multiplication.
50+
51+ Zhu and Lielens have proposed doubling up Python's operators in
52+ this way [1]_. Their proposal would create six new binary infix
53+ operators, and six new in-place operators.
54+
55+ The original version of this proposal was much more conservative.
56+ The author consulted the developers of GNU Octave [2]_, an open
57+ source clone of MATLAB. Its developers agreed that providing an
58+ infix operator for matrix multiplication was important: numerical
59+ programmers really do care whether they have to write ``mmul(A,B)``
60+ instead of ``A op B``.
61+
62+ On the other hand, when asked how important it was to have infix
63+ operators for matrix solution and other operations, Prof. James
64+ Rawlings replied [3]_:
65+
66+ I DON'T think it's a must have, and I do a lot of matrix
67+ inversion. I cannot remember if its A\b or b\A so I always
68+ write inv(A)*b instead. I recommend dropping \.
69+
70+ Based on this discussion, and feedback from students at the US
71+ national laboratories and elsewhere, we recommended adding only
72+ one new operator, for matrix multiplication, to Python.
7073
7174
7275Iterators
76+ =========
7377
74- The planned addition of iterators to Python 2.2 opens up a broader
75- scope for this proposal. As part of the discussion of PEP 201,
76- Lockstep Iteration[4], the author of this proposal conducted an
77- informal usability experiment[5]. The results showed that users
78- are psychologically receptive to "cross-product" loop syntax. For
79- example, most users expected:
78+ The planned addition of iterators to Python 2.2 opens up a broader
79+ scope for this proposal. As part of the discussion of PEP 201,
80+ Lockstep Iteration [4]_ , the author of this proposal con
67DE
ducted an
81+ informal usability experiment [5]_ . The results showed that users
82+ are psychologically receptive to "cross-product" loop syntax. For
83+ example, most users expected: :
8084
81- S = [10, 20, 30]
82- T = [1, 2, 3]
83- for x in S; y in T:
84- print x+y,
85+ S = [10, 20, 30]
86+ T = [1, 2, 3]
87+ for x in S; y in T:
88+ print x+y,
8589
86- to print " 11 12 13 21 22 23 31 32 33" . We believe that users will
87- have the same reaction to:
90+ to print `` 11 12 13 21 22 23 31 32 33`` . We believe that users will
91+ have the same reaction to: :
8892
89- for (x, y) in S @ T:
90- print x+y
93+ for (x, y) in S @ T:
94+ print x+y
9195
92- i.e. that they will naturally interpret this as a tidy way to
93- write loop nests.
96+ i.e. that they will naturally interpret this as a tidy way to
97+ write loop nests.
9498
95- This is where iterators come in. Actually constructing the
96- cross-product of two (or more) sequences before executing the loop
97- would be very expensive. On the other hand, "@" could be defined
98- to get its arguments' iterators, and then create an outer iterator
99- which returns tuples of the values returned by the inner
100- iterators.
99+ This is where iterators come in. Actually constructing the
100+ cross-product of two (or more) sequences before executing the loop
101+ would be very expensive. On the other hand, ``@`` could be defined
102+ to get its arguments' iterators, and then create an outer iterator
103+ which returns tuples of the values returned by the inner
104+ iterators.
101105
102106
103107Discussion
108+ ==========
104109
105- 1. Adding a named function "across" would have less impact on
106- Python than a new infix operator. However, this would not make
107- Python more appealing to numerical programmers, who really do
108- care whether they can write matrix multiplication using an
109- operator, or whether they have to write it as a function call.
110+ 1. Adding a named function "across" would have less impact on
111+ Python than a new infix operator. However, this would not make
112+ Python more appealing to numerical programmers, who really do
113+ care whether they can write matrix multiplication using an
114+ operator, or whether they have to write it as a function call.
110115
111- 2. "@" would have be chainable in the same way as comparison
112- operators, i.e.:
116+ 2. ``@`` would have be chainable in the same way as comparison
117+ operators, i.e.: :
113118
114- (1, 2) @ (3, 4) @ (5, 6)
119+ (1, 2) @ (3, 4) @ (5, 6)
115120
116- would have to return (1, 3, 5) ... (2, 4, 6), and *not*
117- ((1, 3), 5) ... ((2, 4), 6). This should not require special
118- support from the parser, as the outer iterator created by the
119- first "@" could easily be taught how to combine itself with
120- ordinary iterators.
121+ would have to return `` (1, 3, 5) ... (2, 4, 6)`` , and *not*
122+ `` ((1, 3), 5) ... ((2, 4), 6)``` . This should not require special
123+ support from the parser, as the outer iterator created by the
124+ first ``@`` could easily be taught how to combine itself with
125+ ordinary iterators.
121126
122- 3. There would have to be some way to distinguish restartable
123- iterators from ones that couldn't be restarted. For example,
124- if S is an input stream (e.g. a file), and L is a list, then " S
125- @ L" is straightforward, but " L @ S" is not, since iteration
126- through the stream cannot be repeated. This could be treated
127- as an error, or by having the outer iterator detect
128- non-restartable inner iterators and cache their values.
127+ 3. There would have to be some way to distinguish restartable
128+ iterators from ones that couldn't be restarted. For example,
129+ if ``S`` is an input stream (e.g. a file), and ``L`` is a list, then `` S
130+ @ L`` is straightforward, but `` L @ S`` is not, since iteration
131+ through the stream cannot be repeated. This could be treated
132+ as an error, or by having the outer iterator detect
133+ non-restartable inner iterators and cache their values.
129134
130- 4. Whiteboard testing of this proposal in front of three novice
131- Python users (all of them experienced programmers) indicates
132- that users will expect:
135+ 4. Whiteboard testing of this proposal in front of three novice
136+ Python users (all of them experienced programmers) indicates
137+ that users will expect: :
133138
134- "ab" @ "cd"
139+ "ab" @ "cd"
135140
136- to return four strings, not four tuples of pairs of
137- characters. Opinion was divided on what:
141+ to return four strings, not four tuples of pairs of
142+ characters. Opinion was divided on what: :
138143
139- ("a", "b") @ "cd"
144+ ("a", "b") @ "cd"
140145
141- ought to return...
146+ ought to return...
142147
143148
144149Alternatives
150+ ============
145151
146- 1. Do nothing --- keep Python simple.
152+ 1. Do nothing --- keep Python simple.
147153
148- This is always the default choice.
154+ This is always the default choice.
149155
150- 2. Add a named function instead of an operator.
156+ 2. Add a named function instead of an operator.
151157
152- Python is not primarily a numerical language; it may not be worth
153- complexifying it for this special case. However, support for real
154- matrix multiplication *is* frequently requested, and the proposed
155- semantics for "@" for built-in sequence types would simplify
156- expression of a very common idiom (nested loops).
158+ Python is not primarily a numerical language; it may not be worth
159+ complexifying it for this special case. However, support for real
160+ matrix multiplication *is* frequently requested, and the proposed
161+ semantics for ``@`` for built-in sequence types would simplify
162+ expression of a very common idiom (nested loops).
157163
158- 3. Introduce prefixed forms of all existing operators, such as
159- "~*" and "~+" , as proposed in PEP 225 [1].
164+ 3. Introduce prefixed forms of all existing operators, such as
165+ ``~*`` and ``~+`` , as proposed in PEP 225 [1]_ .
160166
161- Our objections to this are that there isn't enough demand to
162- justify the additional complexity (see Rawlings' comments [3]),
163- and that the proposed syntax fails the "low toner" readability
164- test.
167+ Our objections to this are that there isn't enough demand to
168+ justify the additional complexity (see Rawlings' comments [3]_ ),
169+ and that the proposed syntax fails the "low toner" readability
170+ test.
165171
166172
167173Acknowledgments
174+ ===============
168175
169- I am grateful to Huaiyu Zhu for initiating this discussion, and to
170- James Rawlings and students in various Python courses for their
171- discussions of what numerical programmers really care about.
176+ I am grateful to Huaiyu Zhu for initiating this discussion, and to
177+ James Rawlings and students in various Python courses for their
178+ discussions of what numerical programmers really care about.
172179
173180
174181References
182+ ==========
183+
184+ .. [1] PEP 225, Elementwise/Objectwise Operators, Zhu, Lielens
185+ http://www.python.org/dev/peps/pep-0225/
175186
176- [1] PEP 225, Elementwise/Objectwise Operators, Zhu, Lielens
177- http://www.python.org/dev/peps/pep-0225/
187+ .. [2] http://bevo.che.wisc.edu/octave/
178188
179- [2 ] http://bevo.che.wisc.edu/octave/
189+ .. [3 ] http://www.egroups.com/message/python-numeric/4
180190
181- [3] http://www.egroups.com/message/python-numeric/4
191+ .. [4] PEP 201, Lockstep Iteration, Warsaw
192+ http://www.python.org/dev/peps/pep-0201/
182193
183- [4] PEP 201, Lockstep Iteration, Warsaw
184- http://www.python.org/dev/peps/pep-0201/
194+ .. [5] http://mail.python.org/pipermail/python-dev/2000-July/006427.html
185195
186- [5] http://mail.python.org/pipermail/python-dev/2000-July/006427.html
187196
188197
189-
190- Local Variables:
191- mode: indented-text
192- indent-tabs-mode: nil
193- End:
198+ ..
199+ Local Variables:
200+ mode: indented-text
201+ indent-tabs-mode: nil
202+ End:
0 commit comments