Changeset 391 for python/trunk/Doc/howto/functional.rst
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Doc/howto/functional.rst
r2 r391 5 5 :Author: A. M. Kuchling 6 6 :Release: 0.31 7 8 (This is a first draft. Please send comments/error reports/suggestions to9 amk@amk.ca.)10 7 11 8 In this document, we'll take a tour of Python's features suitable for … … 48 45 variants) and Haskell. 49 46 50 The designers of some computer languages choose to emphasize one 51 particular approach to programming. This often makes it difficult to 52 write programs that use a different approach. Other languages are 53 multi-paradigm languages that support several different approaches. 54 Lisp, C++, and Python are multi-paradigm; you can write programs or 55 libraries that are largely procedural, object-oriented, or functional 56 in all of these languages. In a large program, different sections 57 might be written using different approaches; the GUI might be 58 object-oriented while the processing logic is procedural or 47 The designers of some computer languages choose to emphasize one particular 48 approach to programming. This often makes it difficult to write programs that 49 use a different approach. Other languages are multi-paradigm languages that 50 support several different approaches. Lisp, C++, and Python are 51 multi-paradigm; you can write programs or libraries that are largely 52 procedural, object-oriented, or functional in all of these languages. In a 53 large program, different sections might be written using different approaches; 54 the GUI might be object-oriented while the processing logic is procedural or 59 55 functional, for example. 60 56 … … 249 245 and ``"not in"`` operators also support iterators: ``X in iterator`` is true if 250 246 X is found in the stream returned by the iterator. You'll run into obvious 251 problems if the iterator is infinite; ``max()``, ``min()`` , and ``"not in"``247 problems if the iterator is infinite; ``max()``, ``min()`` 252 248 will never return, and if the element X never appears in the stream, the 253 ``"in"`` operatorwon't return either.249 ``"in"`` and ``"not in"`` operators won't return either. 254 250 255 251 Note that you can only go forward in an iterator; there's no way to get the … … 336 332 List comprehensions and generator expressions (short form: "listcomps" and 337 333 "genexps") are a concise notation for such operations, borrowed from the 338 functional programming language Haskell (http://www.haskell.org ). You can strip334 functional programming language Haskell (http://www.haskell.org/). You can strip 339 335 all the whitespace from a stream of strings with the following code:: 340 336 … … 1119 1115 1120 1116 1121 1122 The functional module1123 ---------------------1124 1125 Collin Winter's `functional module <http://oakwinter.com/code/functional/>`__1126 provides a number of more advanced tools for functional programming. It also1127 reimplements several Python built-ins, trying to make them more intuitive to1128 those used to functional programming in other languages.1129 1130 This section contains an introduction to some of the most important functions in1131 ``functional``; full documentation can be found at `the project's website1132 <http://oakwinter.com/code/functional/documentation/>`__.1133 1134 ``compose(outer, inner, unpack=False)``1135 1136 The ``compose()`` function implements function composition. In other words, it1137 returns a wrapper around the ``outer`` and ``inner`` callables, such that the1138 return value from ``inner`` is fed directly to ``outer``. That is, ::1139 1140 >>> def add(a, b):1141 ... return a + b1142 ...1143 >>> def double(a):1144 ... return 2 * a1145 ...1146 >>> compose(double, add)(5, 6)1147 221148 1149 is equivalent to ::1150 1151 >>> double(add(5, 6))1152 221153 1154 The ``unpack`` keyword is provided to work around the fact that Python functions1155 are not always `fully curried <http://en.wikipedia.org/wiki/Currying>`__. By1156 default, it is expected that the ``inner`` function will return a single object1157 and that the ``outer`` function will take a single argument. Setting the1158 ``unpack`` argument causes ``compose`` to expect a tuple from ``inner`` which1159 will be expanded before being passed to ``outer``. Put simply, ::1160 1161 compose(f, g)(5, 6)1162 1163 is equivalent to::1164 1165 f(g(5, 6))1166 1167 while ::1168 1169 compose(f, g, unpack=True)(5, 6)1170 1171 is equivalent to::1172 1173 f(*g(5, 6))1174 1175 Even though ``compose()`` only accepts two functions, it's trivial to build up a1176 version that will compose any number of functions. We'll use ``reduce()``,1177 ``compose()`` and ``partial()`` (the last of which is provided by both1178 ``functional`` and ``functools``). ::1179 1180 from functional import compose, partial1181 1182 multi_compose = partial(reduce, compose)1183 1184 1185 We can also use ``map()``, ``compose()`` and ``partial()`` to craft a version of1186 ``"".join(...)`` that converts its arguments to string::1187 1188 from functional import compose, partial1189 1190 join = compose("".join, partial(map, str))1191 1192 1193 ``flip(func)``1194 1195 ``flip()`` wraps the callable in ``func`` and causes it to receive its1196 non-keyword arguments in reverse order. ::1197 1198 >>> def triple(a, b, c):1199 ... return (a, b, c)1200 ...1201 >>> triple(5, 6, 7)1202 (5, 6, 7)1203 >>>1204 >>> flipped_triple = flip(triple)1205 >>> flipped_triple(5, 6, 7)1206 (7, 6, 5)1207 1208 ``foldl(func, start, iterable)``1209 1210 ``foldl()`` takes a binary function, a starting value (usually some kind of1211 'zero'), and an iterable. The function is applied to the starting value and the1212 first element of the list, then the result of that and the second element of the1213 list, then the result of that and the third element of the list, and so on.1214 1215 This means that a call such as::1216 1217 foldl(f, 0, [1, 2, 3])1218 1219 is equivalent to::1220 1221 f(f(f(0, 1), 2), 3)1222 1223 1224 ``foldl()`` is roughly equivalent to the following recursive function::1225 1226 def foldl(func, start, seq):1227 if len(seq) == 0:1228 return start1229 1230 return foldl(func, func(start, seq[0]), seq[1:])1231 1232 Speaking of equivalence, the above ``foldl`` call can be expressed in terms of1233 the built-in ``reduce`` like so::1234 1235 reduce(f, [1, 2, 3], 0)1236 1237 1238 We can use ``foldl()``, ``operator.concat()`` and ``partial()`` to write a1239 cleaner, more aesthetically-pleasing version of Python's ``"".join(...)``1240 idiom::1241 1242 from functional import foldl, partial from operator import concat1243 1244 join = partial(foldl, concat, "")1245 1246 1247 1117 Revision History and Acknowledgements 1248 1118 ===================================== … … 1300 1170 Mertz also wrote a 3-part series of articles on functional programming 1301 1171 for IBM's DeveloperWorks site; see 1302 `part 1 <http://www-128.ibm.com/developerworks/library/l-prog.html>`__, 1303 `part 2 <http://www-128.ibm.com/developerworks/library/l-prog2.html>`__, and 1304 `part 3 <http://www-128.ibm.com/developerworks/linux/library/l-prog3.html>`__, 1172 1173 `part 1 <http://www.ibm.com/developerworks/linux/library/l-prog/index.html>`__, 1174 `part 2 <http://www.ibm.com/developerworks/linux/library/l-prog2/index.html>`__, and 1175 `part 3 <http://www.ibm.com/developerworks/linux/library/l-prog3/index.html>`__, 1305 1176 1306 1177
Note:
See TracChangeset
for help on using the changeset viewer.