Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Doc/howto/functional.rst

    r2 r391  
    55:Author: A. M. Kuchling
    66:Release: 0.31
    7 
    8 (This is a first draft.  Please send comments/error reports/suggestions to
    9 amk@amk.ca.)
    107
    118In this document, we'll take a tour of Python's features suitable for
     
    4845  variants) and Haskell.
    4946
    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
     47The designers of some computer languages choose to emphasize one particular
     48approach to programming.  This often makes it difficult to write programs that
     49use a different approach.  Other languages are multi-paradigm languages that
     50support several different approaches.  Lisp, C++, and Python are
     51multi-paradigm; you can write programs or libraries that are largely
     52procedural, object-oriented, or functional in all of these languages.  In a
     53large program, different sections might be written using different approaches;
     54the GUI might be object-oriented while the processing logic is procedural or
    5955functional, for example.
    6056
     
    249245and ``"not in"`` operators also support iterators: ``X in iterator`` is true if
    250246X 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"``
     247problems if the iterator is infinite; ``max()``, ``min()``
    252248will never return, and if the element X never appears in the stream, the
    253 ``"in"`` operator won't return either.
     249``"in"`` and ``"not in"`` operators won't return either.
    254250
    255251Note that you can only go forward in an iterator; there's no way to get the
     
    336332List comprehensions and generator expressions (short form: "listcomps" and
    337333"genexps") are a concise notation for such operations, borrowed from the
    338 functional programming language Haskell (http://www.haskell.org).  You can strip
     334functional programming language Haskell (http://www.haskell.org/).  You can strip
    339335all the whitespace from a stream of strings with the following code::
    340336
     
    11191115
    11201116
    1121 
    1122 The functional module
    1123 ---------------------
    1124 
    1125 Collin Winter's `functional module <http://oakwinter.com/code/functional/>`__
    1126 provides a number of more advanced tools for functional programming. It also
    1127 reimplements several Python built-ins, trying to make them more intuitive to
    1128 those used to functional programming in other languages.
    1129 
    1130 This section contains an introduction to some of the most important functions in
    1131 ``functional``; full documentation can be found at `the project's website
    1132 <http://oakwinter.com/code/functional/documentation/>`__.
    1133 
    1134 ``compose(outer, inner, unpack=False)``
    1135 
    1136 The ``compose()`` function implements function composition.  In other words, it
    1137 returns a wrapper around the ``outer`` and ``inner`` callables, such that the
    1138 return value from ``inner`` is fed directly to ``outer``.  That is, ::
    1139 
    1140     >>> def add(a, b):
    1141     ...     return a + b
    1142     ...
    1143     >>> def double(a):
    1144     ...     return 2 * a
    1145     ...
    1146     >>> compose(double, add)(5, 6)
    1147     22
    1148 
    1149 is equivalent to ::
    1150 
    1151     >>> double(add(5, 6))
    1152     22
    1153 
    1154 The ``unpack`` keyword is provided to work around the fact that Python functions
    1155 are not always `fully curried <http://en.wikipedia.org/wiki/Currying>`__.  By
    1156 default, it is expected that the ``inner`` function will return a single object
    1157 and that the ``outer`` function will take a single argument. Setting the
    1158 ``unpack`` argument causes ``compose`` to expect a tuple from ``inner`` which
    1159 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 a
    1176 version that will compose any number of functions. We'll use ``reduce()``,
    1177 ``compose()`` and ``partial()`` (the last of which is provided by both
    1178 ``functional`` and ``functools``). ::
    1179 
    1180     from functional import compose, partial
    1181 
    1182     multi_compose = partial(reduce, compose)
    1183 
    1184 
    1185 We can also use ``map()``, ``compose()`` and ``partial()`` to craft a version of
    1186 ``"".join(...)`` that converts its arguments to string::
    1187 
    1188     from functional import compose, partial
    1189 
    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 its
    1196 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 of
    1211 'zero'), and an iterable.  The function is applied to the starting value and the
    1212 first element of the list, then the result of that and the second element of the
    1213 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 start
    1229 
    1230         return foldl(func, func(start, seq[0]), seq[1:])
    1231 
    1232 Speaking of equivalence, the above ``foldl`` call can be expressed in terms of
    1233 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 a
    1239 cleaner, more aesthetically-pleasing version of Python's ``"".join(...)``
    1240 idiom::
    1241 
    1242     from functional import foldl, partial from operator import concat
    1243 
    1244     join = partial(foldl, concat, "")
    1245 
    1246 
    12471117Revision History and Acknowledgements
    12481118=====================================
     
    13001170Mertz also wrote a 3-part series of articles on functional programming
    13011171for 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>`__,
    13051176
    13061177
Note: See TracChangeset for help on using the changeset viewer.