(************** Content-type: application/mathematica ************** CreatedBy='Mathematica 5.0' Mathematica-Compatible Notebook This notebook can be used with any Mathematica-compatible application, such as Mathematica, MathReader or Publicon. The data for the notebook starts with the line containing stars above. To get the notebook into a Mathematica-compatible application, do one of the following: * Save the data starting with the line of stars above into a file with a name ending in .nb, then open the file inside the application; * Copy the data starting with the line of stars above to the clipboard, then use the Paste menu command inside the application. Data for notebooks contains only printable 7-bit ASCII and can be sent directly in email or through ftp in text mode. Newlines can be CR, LF or CRLF (Unix, Macintosh or MS-DOS style). NOTE: If you modify the data for this notebook not in a Mathematica- compatible application, you must delete the line below containing the word CacheID, otherwise Mathematica-compatible applications may try to use invalid cache data. For more information on notebooks and Mathematica-compatible applications, contact Wolfram Research: web: http://www.wolfram.com email: info@wolfram.com phone: +1-217-398-0700 (U.S.) Notebook reader applications are available free of charge from Wolfram Research. *******************************************************************) (*CacheID: 232*) (*NotebookFileLineBreakTest NotebookFileLineBreakTest*) (*NotebookOptionsPosition[ 15387, 478]*) (*NotebookOutlinePosition[ 16068, 501]*) (* CellTagsIndexPosition[ 16024, 497]*) (*WindowFrame->Normal*) Notebook[{ Cell[CellGroupData[{ Cell["Pure Functions and Functional Programming", "Title"], Cell[CellGroupData[{ Cell["Pure functions", "Section"], Cell[TextData[{ "You can create functions without giving them names. ", StyleBox["Mathematica", FontSlant->"Italic"], " calls these pure functions. Pure functions are useful when you want to \ use a simple function as an argument to a command. For example, suppose that \ we want to list all of the countries whose populations are within three \ standard deviations of the mean. We first read in the data. You will have \ to change the path so that it points to your copy of \ worldpopulation2006.txt." }], "Text"], Cell[BoxData[ \(population = Import["\", \ "\"]\)], "Input"], Cell["Now we find the mean and standard deviation.", "Text"], Cell[BoxData[{ \(\[Mu] = Mean[N[\(Transpose[population]\)[\([2]\)]]]\), "\[IndentingNewLine]", \(\[Sigma] = StandardDeviation[N[\(Transpose[population]\)[\([2]\)]]]\)}], "Input"], Cell[TextData[{ "If all of the square brackets look too cluttered for your tastes, you \ could have used ", StyleBox["Last", FontFamily->"Courier"], " instead of [[2]], since Transpose[population] consists of two elements. \ Its first element is the list of countries and the second element is the list \ of populations." }], "Text"], Cell[BoxData[{ \(\[Mu] = Mean[N[Last[Transpose[population]]]]\), "\[IndentingNewLine]", \(\[Sigma] = StandardDeviation[N[Last[Transpose[population]]]]\)}], "Input"], Cell[TextData[{ "Now let's define a logical function (returns a value of ", StyleBox["True", FontFamily->"Courier"], " or ", StyleBox["False", FontFamily->"Courier"], ") specifying the populations that are within two standard deviations." }], "Text"], Cell[BoxData[{ \(Clear[inRange]\), "\[IndentingNewLine]", \(inRange[country_] := \[Mu] - 2 \[Sigma] \[LessEqual] country[\([2]\)] \[LessEqual] \[Mu] + 2 \[Sigma]\)}], "Input"], Cell["and here it is in action.", "Text"], Cell[BoxData[ \(inRange[{"\", 78887007}]\)], "Input"], Cell[BoxData[ \(inRange[{"\", 298444215}]\)], "Input"], Cell[TextData[{ "We can use the ", StyleBox["Select", FontFamily->"Courier"], " command to extract the values from a list that satisify a logical \ expression. The syntax is ", StyleBox["Select[", FontFamily->"Courier"], StyleBox["list", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", ", FontFamily->"Courier"], StyleBox["criterion", FontFamily->"Courier", FontSlant->"Italic"], StyleBox["]", FontFamily->"Courier"], ". There are the countries within two standard deviations of the mean." }], "Text"], Cell[BoxData[ \(Select[population, inRange]\)], "Input"], Cell["\<\ But if we are only going to use the function inRange for this one \ purpose, then we can create the function on the fly without giving it a name.\ \ \>", "Text"], Cell[BoxData[ \(Select[ population, \((\[Mu] - 2 \[Sigma] \[LessEqual] #[\([2]\)] \[LessEqual] \[Mu] + 2 \[Sigma])\) &]\)], "Input"], Cell[TextData[{ StyleBox["(\[Mu]-2\[Sigma]\[LessEqual]#[[2]]\[LessEqual]\[Mu]+2\[Sigma])&", FontFamily->"Courier"], " is a pure function. Its argument is represented by a # sign. If a pure \ function has more than one argument, then its arguments are represented by \ #1, #2, #3, etc. The argument for a pure function of one variable can be \ represented as # or #1. Pure functions have to end with an & symbol." }], "Text"], Cell[TextData[{ StyleBox["Exercise 13.1:", FontWeight->"Bold", FontColor->RGBColor[0, 0.500008, 0.250004]], " List the countries and their populations that are more than three \ standard deviations from the mean. These countries are outliers." }], "Text", Background->GrayLevel[0.750011]], Cell[TextData[{ StyleBox["Exercise 13.2:", FontWeight->"Bold", FontColor->RGBColor[0, 0.500008, 0.250004]], " Use Select and a pure function to extract palindrones from a list of \ words. A palindrone is a word that is the same spelled forwards or \ backwards, such as \"radar\" and \"noon\". You may have to look up some \ additional ", StyleBox["Mathematica", FontSlant->"Italic"], " commands in the Help Browser for working with character strings." }], "Text", Background->GrayLevel[0.750011]], Cell[TextData[{ "Another command commonly use with pure functions is ", StyleBox["Array", FontFamily->"Courier"], ", which is similar to ", StyleBox["Table", FontFamily->"Courier"], ". ", StyleBox["Array[f, n]", FontFamily->"Courier"], " evaluates the function, ", StyleBox["f", FontSlant->"Italic"], ", at 1, 2, \[Ellipsis]", ", ", StyleBox["n", FontSlant->"Italic"], ", ", "creating the list ", StyleBox["{f[1], f[2], \[Ellipsis], f[n]}", FontFamily->"Courier"], ". Here are the first 100 perfect squares written using named function, ", StyleBox["square", FontFamily->"Courier"], "." }], "Text"], Cell[BoxData[{ \(Clear[square]\), "\[IndentingNewLine]", \(\(square[x_] = x\^2;\)\), "\[IndentingNewLine]", \(Array[square, 100]\)}], "Input"], Cell["and here is the same list created with a pure function.", "Text"], Cell[BoxData[ \(Array[#1\^2 &, 100]\)], "Input"], Cell[TextData[{ StyleBox["Exercise 13.3:", FontWeight->"Bold", FontColor->RGBColor[0, 0.500008, 0.250004]], " Construct a pure function as the second argument to Sort so that it will \ aphabetize names of the form {\"Firstname\", \"Lastname\"}. Test it on the \ list of U.S. presidents given below." }], "Text", Background->GrayLevel[0.750011]], Cell[BoxData[ \(\(presidents = {{"\", "\"}, {"\", "\"}, {"\", "\"}, {"\", "\"}, \ {"\", "\"}, {"\", "\"}, {"\", \ "\"}, {"\", "\"}, {"\", \ "\"}, {"\", "\"}, {"\", "\"}, \ {"\", "\"}, {"\", "\"}, \ {"\", "\"}, {"\", "\"}, \ {"\", "\"}, {"\", "\"}, \ {"\", "\"}, {"\", "\"}, {"\", \ "\"}, {"\", "\"}, {"\", \ "\"}, {"\", "\"}, {"\", \ "\"}, {"\", "\"}, {"\", \ "\"}, {"\", "\"}, {"\", "\"}, \ {"\", "\"}, {"\", "\"}, \ {"\", "\"}, {"\", "\"}, \ {"\", "\"}, {"\", "\"}, {"\", "\ \"}, {"\", "\"}, {"\", "\"}, \ {"\", "\"}, {"\", "\"}, {"\", \ "\"}, {"\", "\"}, {"\", "\"}, {"\ \", "\"}};\)\)], "Input"], Cell[TextData[{ "The ", StyleBox["Mathematica", FontSlant->"Italic"], " Book describes pure functions in Principles of \ Mathematica\[Rule]Functional Operations\[Rule]2.2.5 Pure Functions." }], "Text"] }, Closed]], Cell[CellGroupData[{ Cell["Functional Programming", "Section"], Cell[TextData[{ "Most commonly used programming languages, such as C and Java, are \ procedural programming languages. This is the type of programming that we \ used in the Section 11, Functions. Procedural programming consists of \ sequences of statements, evaluated one after the next, unless branching \ statements (such as If and Which) or loop structures (such as Do or While) \ alter the order of statement evaluation. In contrast to procedural \ programming, functional programming is a composition of functions. The \ output of one function is input to the next function, such as ", StyleBox["f[g[h[x]]]", FontFamily->"Courier"], ". Any program that can be written as a procedural program can also be \ written as a functional program. ", StyleBox["Mathematica", FontSlant->"Italic"], " supports both procedural programming and functional programming. Because \ of the way it is designed, ", StyleBox["Mathematica", FontSlant->"Italic"], " functional programs usually execute in less time than the corresponding \ procedural program." }], "Text"], Cell[TextData[{ "Two of the most important functional programming commands are ", StyleBox["Apply", FontFamily->"Courier"], " and ", StyleBox["Map", FontFamily->"Courier"], "." }], "Text"], Cell[TextData[{ "The syntax of ", StyleBox["Apply", FontFamily->"Courier"], " is ", StyleBox["Apply[", FontFamily->"Courier"], StyleBox["function", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", ", FontFamily->"Courier"], StyleBox["list", FontFamily->"Courier", FontSlant->"Italic"], StyleBox["]", FontFamily->"Courier"], ". Apply replaces the head of ", StyleBox["list", FontFamily->"Courier", FontSlant->"Italic"], " with ", StyleBox["function", FontFamily->"Courier", FontSlant->"Italic"], "." }], "Text"], Cell[BoxData[{ \(Clear[f, a, b, c]\), "\[IndentingNewLine]", \(Apply[f, {a, b, c, d}]\)}], "Input"], Cell["\<\ What does the following function do? If you are having trouble \ figuring it out, try performing the operation on a symbolic list, \ Apply[Times,{a, b, c, d}]. Then evaluate Range[6], if you forget what Range \ does.\ \>", "Text"], Cell[BoxData[{ \(Clear[unknownFunction]\), "\[IndentingNewLine]", \(unknownFunction[n_] := Apply[Times, Range[n]]\)}], "Input"], Cell["\<\ Apply is actually more general than described above. The second \ argument does not have to have a head of List. In our next example, we use \ Apply to extract the RGB values, as a list, from any color named in \ Graphics`Colors`. \ \>", "Text"], Cell[BoxData[{ \(Needs["\"]\), "\[IndentingNewLine]", \(Red\), "\[IndentingNewLine]", \(Apply[List, Red]\)}], "Input"], Cell[TextData[{ "The head of Red is ", StyleBox["RGBColor", FontFamily->"Courier"], ". We replace that head with ", StyleBox["List", FontFamily->"Courier"], ", to create a list of red, green, and blue values." }], "Text"], Cell[TextData[{ "Now we can take a linear combination of two colors to get a new list of \ RGB values. At ", StyleBox["x", FontSlant->"Italic"], " = 0, we get ", StyleBox["Red", FontFamily->"Courier"], " and at ", StyleBox["x", FontSlant->"Italic"], " = 1, we get ", StyleBox["Yellow", FontFamily->"Courier"], "." }], "Text"], Cell[BoxData[ \(mixedColorList = \((1 - x)\)*Apply[List, Red] + x*Apply[List, Yellow]\)], "Input"], Cell["\<\ If we want this list to represent a color, we have to replace its \ head, List, with the head RGBColor.\ \>", "Text"], Cell[BoxData[ \(Apply[RGBColor, mixedColorList]\)], "Input"], Cell["And now we can combine all of these steps into one function.", "Text"], Cell[BoxData[ \(colorGradient[x_, color1_RGBColor, color2_RGBColor] := Apply[RGBColor, \((1 - x)\)*Apply[List, color1] + x*Apply[List, color2]]\)], "Input"], Cell["\<\ Here is a combination of of 25% red and 75% yellow, that is, a hue \ of orange.\ \>", "Text"], Cell[BoxData[ \(colorGradient[ .75, Red, Yellow]\)], "Input"], Cell["\<\ Here is a plot of ten colors ranging from red to yellow. Notice \ how we used a pure function as the ColorFunction argument.\ \>", "Text"], Cell[BoxData[{ \(\(n = 100;\)\), "\[IndentingNewLine]", \(gradient = Table[x, {x, 0, 1, 1/n}]\), "\[IndentingNewLine]", \(\(ListDensityPlot[{gradient, gradient}, ColorFunction \[Rule] \((colorGradient[#, Red, Yellow] &)\), Mesh \[Rule] False];\)\)}], "Input"], Cell["\<\ Try several other colors and see if you can get some nice color \ gradients.\ \>", "Text"], Cell[TextData[{ "Other programming languages support some or all functional programming \ features, too. Lisp and Smalltalk are purely functional programming \ languages. Like ", StyleBox["Mathematica", FontSlant->"Italic"], ", Perl and Matlab support both functional programming and procedural \ programming. In ", StyleBox["Mathematica", FontSlant->"Italic"], ", functional programs almost always execute faster than procedural \ programs." }], "Text"], Cell[TextData[{ StyleBox["Exercise 13.4:", FontWeight->"Bold", FontColor->RGBColor[0, 0.500008, 0.250004]], " Create a function that accepts symbols, ", StyleBox["x", FontSlant->"Italic"], " and ", StyleBox["y", FontSlant->"Italic"], ", and a positive integer, ", StyleBox["n", FontSlant->"Italic"], ", and", " returns a list of the terms in the binomial expansion of ", Cell[BoxData[ \(TraditionalForm\`\((x + y)\)\^n\)]], "." }], "Text", Background->GrayLevel[0.750011]], Cell[TextData[{ "In the next section, we will look at other powerful functional programming \ commands. The ", StyleBox["Mathematica", FontSlant->"Italic"], " Book describes functional programming in Principles of \ Mathematica\[Rule]2.2 Functional Operations." }], "Text"] }, Closed]] }, Open ]] }, FrontEndVersion->"5.0 for Microsoft Windows", ScreenRectangle->{{0, 1024}, {0, 695}}, WindowSize->{949, 666}, WindowMargins->{{0, Automatic}, {Automatic, 0}}, StyleDefinitions -> "PastelColor.nb" ] (******************************************************************* Cached data follows. If you edit this Notebook file directly, not using Mathematica, you must remove the line containing CacheID at the top of the file. The cache data will then be recreated when you save this file from within Mathematica. *******************************************************************) (*CellTagsOutline CellTagsIndex->{} *) (*CellTagsIndex CellTagsIndex->{} *) (*NotebookFileOutline Notebook[{ Cell[CellGroupData[{ Cell[1776, 53, 58, 0, 184, "Title"], Cell[CellGroupData[{ Cell[1859, 57, 33, 0, 51, "Section"], Cell[1895, 59, 529, 10, 71, "Text"], Cell[2427, 71, 187, 4, 78, "Input"], Cell[2617, 77, 60, 0, 29, "Text"], Cell[2680, 79, 201, 4, 58, "Input"], Cell[2884, 85, 344, 8, 50, "Text"], Cell[3231, 95, 180, 3, 58, "Input"], Cell[3414, 100, 268, 8, 29, "Text"], Cell[3685, 110, 195, 3, 58, "Input"], Cell[3883, 115, 41, 0, 29, "Text"], Cell[3927, 117, 65, 1, 38, "Input"], Cell[3995, 120, 74, 1, 38, "Input"], Cell[4072, 123, 563, 19, 51, "Text"], Cell[4638, 144, 60, 1, 38, "Input"], Cell[4701, 147, 171, 4, 29, "Text"], Cell[4875, 153, 174, 4, 38, "Input"], Cell[5052, 159, 437, 7, 50, "Text"], Cell[5492, 168, 303, 7, 35, "Text"], Cell[5798, 177, 520, 12, 56, "Text"], Cell[6321, 191, 662, 25, 50, "Text"], Cell[6986, 218, 156, 3, 78, "Input"], Cell[7145, 223, 71, 0, 29, "Text"], Cell[7219, 225, 52, 1, 39, "Input"], Cell[7274, 228, 359, 8, 56, "Text"], Cell[7636, 238, 1435, 20, 218, "Input"], Cell[9074, 260, 211, 6, 29, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[9322, 271, 41, 0, 35, "Section"], Cell[9366, 273, 1088, 21, 134, "Text"], Cell[10457, 296, 206, 8, 29, "Text"], Cell[10666, 306, 593, 26, 30, "Text"], Cell[11262, 334, 108, 2, 58, "Input"], Cell[11373, 338, 242, 5, 50, "Text"], Cell[11618, 345, 136, 2, 58, "Input"], Cell[11757, 349, 258, 5, 50, "Text"], Cell[12018, 356, 151, 3, 78, "Input"], Cell[12172, 361, 240, 8, 29, "Text"], Cell[12415, 371, 360, 15, 29, "Text"], Cell[12778, 388, 111, 2, 38, "Input"], Cell[12892, 392, 127, 3, 29, "Text"], Cell[13022, 397, 64, 1, 38, "Input"], Cell[13089, 400, 76, 0, 29, "Text"], Cell[13168, 402, 178, 3, 38, "Input"], Cell[13349, 407, 103, 3, 29, "Text"], Cell[13455, 412, 65, 1, 38, "Input"], Cell[13523, 415, 149, 3, 29, "Text"], Cell[13675, 420, 291, 5, 78, "Input"], Cell[13969, 427, 100, 3, 29, "Text"], Cell[14072, 432, 475, 12, 71, "Text"], Cell[14550, 446, 522, 19, 35, "Text"], Cell[15075, 467, 284, 7, 50, "Text"] }, Closed]] }, Open ]] } ] *) (******************************************************************* End of Mathematica Notebook file. *******************************************************************)