(* Content-type: application/mathematica *) (*** Wolfram Notebook File ***) (* http://www.wolfram.com/nb *) (* CreatedBy='Mathematica 6.0' *) (*CacheID: 234*) (* Internal cache information: NotebookFileLineBreakTest NotebookFileLineBreakTest NotebookDataPosition[ 145, 7] NotebookDataLength[ 56817, 1719] NotebookOptionsPosition[ 49011, 1458] NotebookOutlinePosition[ 49393, 1475] CellTagsIndexPosition[ 49350, 1472] WindowFrame->Normal ContainsDynamic->True *) (* Beginning of Notebook Content *) Notebook[{ Cell[CellGroupData[{ Cell[TextData[{ "Changing attributes of pure functions at run-time with \t\t\t", StyleBox["AttributesOfPureFunctions`", FontWeight->"Bold", FontSlant->"Italic"] }], "Subtitle", CellChangeTimes->{{3.441615231458573*^9, 3.4416152651069565`*^9}, { 3.4416153789406414`*^9, 3.441615402594654*^9}, {3.441900027974229*^9, 3.4419000955213566`*^9}, {3.4419002706932416`*^9, 3.441900272986539*^9}, { 3.442077012517704*^9, 3.442077033808318*^9}, {3.4420771447378273`*^9, 3.4420771537407727`*^9}, {3.442245784957608*^9, 3.4422458211296206`*^9}}], Cell[CellGroupData[{ Cell["\<\ Author: \t\t\tLeonid B. Shifrin \t\t\t \t\t\tleonid@mathprogramming-intro.org, \t\t\tshifrinl@hotmail.com\ \>", "Subsection", CellChangeTimes->{{3.4416153043333616`*^9, 3.441615358240877*^9}, { 3.4416175573931026`*^9, 3.441617572254472*^9}}, FontWeight->"Plain"], Cell["Package version 1.0 - January 2009", "Subsubsection", CellChangeTimes->{{3.441703718150744*^9, 3.441703747372763*^9}}, FontWeight->"Plain"], Cell[TextData[{ StyleBox["Mathematica", FontSlant->"Italic"], " version 5.0+ (untested for earlier versions) " }], "Subsubsection", CellChangeTimes->{{3.4417037513885374`*^9, 3.4417037599107924`*^9}, { 3.441703818074427*^9, 3.4417038219600143`*^9}, 3.4418064057502337`*^9, { 3.4419001043340287`*^9, 3.4419001324043922`*^9}, {3.4420770398970737`*^9, 3.4420770535667295`*^9}}, FontWeight->"Plain"] }, Open ]], Cell[CellGroupData[{ Cell["Introduction", "Section", CellChangeTimes->{{3.4420769092191677`*^9, 3.442076914156267*^9}}, FontWeight->"Plain"], Cell[TextData[{ "This is a small package which allows to take a given pure function and \ \"manufacture\" from it another one, with a different set of attributes. This \ may be useful in various circumstances, for instance when a pure (unnamed) \ function is passed as an argument, and while we don' t have access to its \ name (it has no name), we want to ensure that its behavior is consistent with \ a given set of attributes (of which not all may be initially present in this \ pure function, and some that are present we may wish to disable). We can also \ convert the \"normal\" (DownValue-based) function into a pure function, but \ not all attributes acceptable for a symbol are legal in a pure function, so \ in general one can not assume that the \"converted\" pure function can be \ used everywhere where the original one is used, with the same effect.\n\nAn \ important thing to remember is that all functions of this package do not (and \ can not) change the \"initial\" pure function (since it is an expression, not \ an L-value), but rather produce a copy function with the desired set of \ attributes. This is consistent with the general trend of avoiding \ side-effects in idiomatic ", StyleBox["Mathematica", FontSlant->"Italic"], " programming." }], "Text", CellChangeTimes->{{3.4422446180596914`*^9, 3.4422451054204817`*^9}, { 3.442252148878477*^9, 3.442252155678254*^9}, {3.4422522028761215`*^9, 3.4422522030063086`*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Illustration", "Section", CellChangeTimes->{{3.4422445046766543`*^9, 3.4422445084721117`*^9}}, FontWeight->"Plain"], Cell[CellGroupData[{ Cell["Setup", "Subsection", CellChangeTimes->{{3.4352426087977314`*^9, 3.435242611121072*^9}}, FontWeight->"Plain"], Cell[TextData[{ "Let the Mathematica know where to look for the package (", StyleBox["use your directory here", FontWeight->"Bold", FontSlant->"Italic"], ")" }], "Text", CellChangeTimes->{{3.4422457220771904`*^9, 3.442245743548064*^9}}], Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{ RowBox[{"If", "[", RowBox[{ RowBox[{"Not", "[", RowBox[{"MemberQ", "[", RowBox[{"$Path", ",", "#"}], "]"}], "]"}], ",", RowBox[{"AppendTo", "[", RowBox[{"$Path", ",", "#"}], "]"}]}], "]"}], "&"}], "@", "\"\\""}], ";"}]], "Input", CellChangeTimes->{{3.435241553820749*^9, 3.4352415928969374`*^9}}], Cell["Load the package :", "Text", CellChangeTimes->{{3.4422457117223005`*^9, 3.442245715557816*^9}}], Cell[BoxData[ RowBox[{"Needs", "[", "\"\\"", "]"}]], "Input", CellChangeTimes->{{3.435241546189776*^9, 3.4352415470510144`*^9}, { 3.4352415972131443`*^9, 3.43524160878979*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"?", "AttributesOfPureFunctions`*"}]], "Input", CellChangeTimes->{{3.4352416228900657`*^9, 3.435241624482355*^9}}], Cell[BoxData[ DynamicModuleBox[{Typeset`open$$ = True}, PaneSelectorBox[{False-> RowBox[{ OpenerBox[Dynamic[Typeset`open$$], ImageSize->Small], StyleBox["AttributesOfPureFunctions`", "InfoHeading"]}], True->GridBox[{ { RowBox[{ OpenerBox[Dynamic[Typeset`open$$], ImageSize->Small], StyleBox["AttributesOfPureFunctions`", "InfoHeading"]}]}, {GridBox[{ { ButtonBox["ClearPFAttributes", BaseStyle->"InformationLink", ButtonData:>{ "Info3442225020-8947027", "AttributesOfPureFunctions`ClearPFAttributes"}, ButtonNote->"AttributesOfPureFunctions`"], ButtonBox["RemovePFAttributes", BaseStyle->"InformationLink", ButtonData:>{ "Info3442225020-8947027", "AttributesOfPureFunctions`RemovePFAttributes"}, ButtonNote->"AttributesOfPureFunctions`"], ButtonBox["ToPureFunction", BaseStyle->"InformationLink", ButtonData:>{ "Info3442225020-8947027", "AttributesOfPureFunctions`ToPureFunction"}, ButtonNote->"AttributesOfPureFunctions`"]}, { ButtonBox["GetPFAttributes", BaseStyle->"InformationLink", ButtonData:>{ "Info3442225020-8947027", "AttributesOfPureFunctions`GetPFAttributes"}, ButtonNote->"AttributesOfPureFunctions`"], ButtonBox["SetPFAttributes", BaseStyle->"InformationLink", ButtonData:>{ "Info3442225020-8947027", "AttributesOfPureFunctions`SetPFAttributes"}, ButtonNote->"AttributesOfPureFunctions`"], ""} }, DefaultBaseStyle->"InfoGrid", GridBoxItemSize->{"Columns" -> {{ Scaled[0.31666666666666665`]}}}]} }, GridBoxAlignment->{"Columns" -> {{Left}}, "Rows" -> {{Baseline}}}]}, Dynamic[Typeset`open$$], ImageSize->Automatic]]], "Print", "InfoCell", CellChangeTimes->{3.4422538207124557`*^9}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["Operations with pure functions with named arguments", "Subsection", CellChangeTimes->{{3.4422436772869263`*^9, 3.442243693530283*^9}}, FontWeight->"Plain"], Cell["Here is a pure function :", "Text", CellChangeTimes->{{3.4422513463745327`*^9, 3.4422513513917475`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"fp0", " ", "=", RowBox[{"Function", "[", RowBox[{"x", ",", RowBox[{"x", "^", "2"}]}], "]"}]}], ";"}]], "Input", CellChangeTimes->{{3.442230558633229*^9, 3.4422305678364625`*^9}, { 3.4422424754287395`*^9, 3.442242533352029*^9}}], Cell["It has no attributes", "Text", CellChangeTimes->{{3.442251356368904*^9, 3.4422513608152976`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"GetPFAttributes", "[", "fp0", "]"}]], "Input", CellChangeTimes->{ 3.4422305874346433`*^9, {3.442240733413845*^9, 3.4422407372093024`*^9}}], Cell[BoxData[ RowBox[{"{", "}"}]], "Output", CellChangeTimes->{ 3.4422305879153347`*^9, 3.442230792118965*^9, 3.442231204241568*^9, 3.442238032870654*^9, 3.44223843844384*^9, {3.442240724651245*^9, 3.442240737700008*^9}, 3.442240823142869*^9, 3.4422412779368305`*^9, { 3.4422424896592016`*^9, 3.4422425345337276`*^9}, 3.442243159282072*^9, 3.4422440705624285`*^9, 3.4422513413473043`*^9, 3.4422529282992287`*^9, 3.442253001804925*^9, 3.4422533838242416`*^9, 3.442253653922624*^9, 3.442253823456402*^9}] }, Open ]], Cell["We now set a HoldFirst and Flat attributes :", "Text", CellChangeTimes->{{3.4422513677953343`*^9, 3.4422514024451585`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fp01", "=", RowBox[{"SetPFAttributes", "[", RowBox[{"fp0", ",", RowBox[{"{", RowBox[{"HoldFirst", ",", "Flat"}], "}"}]}], "]"}]}]], "Input", CellChangeTimes->{{3.4422305935434275`*^9, 3.4422305940040894`*^9}, { 3.44223069171459*^9, 3.442230739363106*^9}, 3.442240834989904*^9, { 3.4422514040875196`*^9, 3.4422514053994064`*^9}, {3.4422536903049393`*^9, 3.4422537076598945`*^9}}], Cell[BoxData[ RowBox[{"Function", "[", RowBox[{"x", ",", SuperscriptBox["x", "2"], ",", RowBox[{"{", RowBox[{"Flat", ",", "HoldFirst"}], "}"}]}], "]"}]], "Output", CellChangeTimes->{{3.4422307128449745`*^9, 3.442230739903883*^9}, 3.4422307932606063`*^9, 3.442231205413253*^9, 3.4422380339221663`*^9, 3.442238439425251*^9, 3.442240835520667*^9, 3.4422411902607584`*^9, 3.442241220344016*^9, 3.442241278707939*^9, {3.4422424903802385`*^9, 3.4422425350544767`*^9}, 3.44224316023344*^9, 3.442244071664013*^9, { 3.4422513814449615`*^9, 3.442251406170515*^9}, 3.4422529289601793`*^9, 3.442253003307085*^9, 3.442253385296358*^9, 3.442253655615058*^9, { 3.4422536918371425`*^9, 3.4422537082607584`*^9}, 3.442253823846963*^9}] }, Open ]], Cell["Removing the attribute :", "Text", CellChangeTimes->{{3.442242343729365*^9, 3.4422423844278865`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"RemovePFAttributes", "[", RowBox[{"fp01", ",", "HoldFirst"}], "]"}]], "Input", CellChangeTimes->{{3.442238166342578*^9, 3.442238194693344*^9}, 3.4422408146706867`*^9, {3.442253046899768*^9, 3.442253049663742*^9}}], Cell[BoxData[ RowBox[{"Function", "[", RowBox[{"x", ",", SuperscriptBox["x", "2"], ",", RowBox[{"{", "Flat", "}"}]}], "]"}]], "Output", CellChangeTimes->{{3.442238178550131*^9, 3.4422381952140927`*^9}, 3.4422384413780594`*^9, 3.4422408382545986`*^9, 3.442241191202112*^9, 3.442241280210099*^9, 3.4422425360659313`*^9, 3.4422431613049808`*^9, 3.4422440724851933`*^9, {3.4422513842690225`*^9, 3.44225140934508*^9}, 3.4422530503347073`*^9, 3.442253386067467*^9, 3.442253657197333*^9, 3.4422538250386767`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"RemovePFAttributes", "[", RowBox[{"fp01", ",", "Hold"}], "]"}]], "Input", CellChangeTimes->{{3.4422530327193775`*^9, 3.442253055792555*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"RemovePFAttributes", "::", "\<\"unknwn\"\>"}], RowBox[{ ":", " "}], "\<\"Can not remove unknown (or invalid for a pure function) \ attribute(s) \\!\\({Hold}\\) \"\>"}]], "Message", "MSG", CellChangeTimes->{3.4422530570743985`*^9, 3.4422533888815136`*^9, 3.442253659300357*^9, 3.442253714740075*^9, 3.4422538268913407`*^9}], Cell[BoxData[ RowBox[{"RemovePFAttributes", "[", RowBox[{ RowBox[{"Function", "[", RowBox[{"x", ",", SuperscriptBox["x", "2"], ",", RowBox[{"{", RowBox[{"Flat", ",", "HoldFirst"}], "}"}]}], "]"}], ",", "Hold"}], "]"}]], "Output", CellChangeTimes->{{3.442253034151437*^9, 3.442253057885565*^9}, 3.4422533889115567`*^9, 3.442253659320386*^9, 3.4422537147901473`*^9, 3.4422538269313984`*^9}] }, Open ]], Cell["Or, we can clear all presently set attributes :", "Text", CellChangeTimes->{{3.442242386721184*^9, 3.4422424017327695`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"ClearPFAttributes", "[", "fp01", "]"}]], "Input", CellChangeTimes->{{3.442238106446451*^9, 3.442238116961571*^9}, 3.442240797125458*^9, {3.442253726056347*^9, 3.442253726226592*^9}, { 3.442253833721162*^9, 3.442253845247736*^9}}], Cell[BoxData[ RowBox[{"Function", "[", RowBox[{"x", ",", SuperscriptBox["x", "2"]}], "]"}]], "Output", CellChangeTimes->{ 3.4422381173220897`*^9, 3.4422384427099743`*^9, 3.4422408397667727`*^9, 3.4422411922135663`*^9, 3.442241281081352*^9, 3.4422425371675153`*^9, 3.442243162266363*^9, 3.4422440734766192`*^9, {3.442251388695387*^9, 3.4422514117585506`*^9}, {3.4422537204783263`*^9, 3.442253727598565*^9}, { 3.4422538298756323`*^9, 3.4422538457083983`*^9}}] }, Open ]], Cell["\<\ Let us remember that the original function did not change : all our \ operations produce copies :\ \>", "Text", CellChangeTimes->{{3.442242405568285*^9, 3.44224243669304*^9}}], Cell[CellGroupData[{ Cell[BoxData["fp01"], "Input", CellChangeTimes->{{3.4422424431322994`*^9, 3.442242444053624*^9}}], Cell[BoxData[ RowBox[{"Function", "[", RowBox[{"x", ",", SuperscriptBox["x", "2"], ",", RowBox[{"{", RowBox[{"Flat", ",", "HoldFirst"}], "}"}]}], "]"}]], "Output", CellChangeTimes->{3.442242444344042*^9, 3.4422425385495024`*^9, 3.4422431641290417`*^9, 3.442244074928707*^9, 3.442251415053288*^9, 3.4422538503350515`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"GetPFAttributes", "[", "fp01", "]"}]], "Input", CellChangeTimes->{3.4422307428581314`*^9, 3.44224077421251*^9}], Cell[BoxData[ RowBox[{"{", RowBox[{"Flat", ",", "HoldFirst"}], "}"}]], "Output", CellChangeTimes->{{3.4422307305504336`*^9, 3.4422307431185055`*^9}, 3.4422312096092863`*^9, 3.4422380355044413`*^9, 3.442238444352336*^9, 3.442240841198832*^9, 3.4422411935254526`*^9, 3.4422412824733534`*^9, 3.4422425395008707`*^9, 3.442243164930194*^9, 3.4422440758099747`*^9, 3.442251417066182*^9, 3.442253851326477*^9}] }, Open ]], Cell[TextData[{ "Can not set an attribute which is either unknown to ", StyleBox["Mathematica", FontSlant->"Italic"], ", or not legal to be set in a pure function :" }], "Text", CellChangeTimes->{{3.442242310631773*^9, 3.4422423270353603`*^9}, { 3.442251431607091*^9, 3.442251461940709*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"SetPFAttributes", "[", RowBox[{"fp0", ",", RowBox[{"{", "Hold", "}"}]}], "]"}]], "Input", CellChangeTimes->{3.442239625100168*^9, 3.4422407590607233`*^9, 3.442241216117939*^9}], Cell[BoxData[ RowBox[{ RowBox[{"SetPFAttributes", "::", "\<\"unknwn\"\>"}], RowBox[{ ":", " "}], "\<\"Can not set unknown (or invalid for a pure function) \ attribute(s) \\!\\({Hold}\\) \"\>"}]], "Message", "MSG", CellChangeTimes->{ 3.44223962574109*^9, 3.44224084456367*^9, {3.442241194356648*^9, 3.44224121668876*^9}, 3.4422412839354563`*^9, 3.4422425407526703`*^9, 3.4422431661118927`*^9, 3.442244076821429*^9, 3.442251425167832*^9, 3.44225385386012*^9}], Cell[BoxData[ RowBox[{"SetPFAttributes", "[", RowBox[{ RowBox[{"Function", "[", RowBox[{"x", ",", SuperscriptBox["x", "2"]}], "]"}], ",", RowBox[{"{", "Hold", "}"}]}], "]"}]], "Output", CellChangeTimes->{ 3.4422408453948655`*^9, {3.442241194386691*^9, 3.442241216728818*^9}, 3.442241283965499*^9, 3.442242540782714*^9, 3.442243166161965*^9, 3.442244076851472*^9, 3.4422514252078896`*^9, 3.4422538538901634`*^9}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["Anonymous pure functions", "Subsection", CellChangeTimes->{{3.442243704566152*^9, 3.442243709963914*^9}, 3.442251264266467*^9}, FontWeight->"Plain"], Cell["\<\ We can also work with functions defined with # - & notation :\ \>", "Text", CellChangeTimes->{{3.442242552830037*^9, 3.442242572117771*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fp1", " ", "=", " ", RowBox[{ RowBox[{"#", "^", "2"}], "&"}]}]], "Input", CellChangeTimes->{{3.442231250478053*^9, 3.442231260222064*^9}}], Cell[BoxData[ RowBox[{ SuperscriptBox["#1", "2"], "&"}]], "Output", CellChangeTimes->{3.442231260852971*^9, 3.4422380374272065`*^9, 3.442238446205*^9, 3.4422412968139744`*^9, 3.442242587129357*^9, 3.4422431692864575`*^9, 3.4422440784637904`*^9, 3.4422514681496367`*^9, 3.4422538580361247`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"GetPFAttributes", "[", "fp1", "]"}]], "Input", CellChangeTimes->{{3.4422312689946785`*^9, 3.442231269074794*^9}, 3.4422407747232447`*^9}], Cell[BoxData[ RowBox[{"{", "}"}]], "Output", CellChangeTimes->{3.442231269395254*^9, 3.4422380425645933`*^9, 3.4422384490190463`*^9, 3.4422413022017217`*^9, 3.442242588531373*^9, 3.4422431699574223`*^9, 3.4422440793650866`*^9, 3.44225146927125*^9, 3.4422538586570177`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fp11", "=", RowBox[{"SetPFAttributes", "[", RowBox[{"fp1", ",", RowBox[{"{", "HoldFirst", "}"}]}], "]"}]}]], "Input", CellChangeTimes->{{3.442231276916069*^9, 3.442231279279467*^9}, 3.442240759571458*^9}], Cell[BoxData[ RowBox[{"Function", "[", RowBox[{"Null", ",", SuperscriptBox["#1", "2"], ",", RowBox[{"{", "HoldFirst", "}"}]}], "]"}]], "Output", CellChangeTimes->{ 3.442231279820245*^9, 3.4422380442770557`*^9, 3.4422384502708464`*^9, 3.4422413047453794`*^9, {3.4422425809104147`*^9, 3.442242589142251*^9}, 3.4422431711891937`*^9, 3.4422440802563677`*^9, 3.4422514702927184`*^9, 3.4422538593780546`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"GetPFAttributes", "[", "fp11", "]"}]], "Input", CellChangeTimes->{3.442231293850419*^9, 3.442240775274037*^9}], Cell[BoxData[ RowBox[{"{", "HoldFirst", "}"}]], "Output", CellChangeTimes->{3.442231294130822*^9, 3.4422380540010386`*^9, 3.4422384522737265`*^9, 3.4422413109342785`*^9, 3.4422425926673203`*^9, 3.442243172471037*^9, 3.442244081488139*^9, 3.442251472035224*^9, 3.4422538605797825`*^9}] }, Open ]], Cell["Go back to the original function :", "Text", CellChangeTimes->{{3.442242280768832*^9, 3.4422422886902227`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"RemovePFAttributes", "[", RowBox[{"fp11", ",", RowBox[{"{", "HoldFirst", "}"}]}], "]"}]], "Input", CellChangeTimes->{{3.4422382089438353`*^9, 3.4422382168051395`*^9}, 3.442240815511896*^9}], Cell[BoxData[ RowBox[{ SuperscriptBox["#1", "2"], "&"}]], "Output", CellChangeTimes->{{3.442238209394483*^9, 3.4422382172858305`*^9}, 3.4422384532551374`*^9, 3.442241313147461*^9, 3.442242594249595*^9, 3.4422431733122463`*^9, 3.4422440823994493`*^9, 3.442251473637528*^9, 3.442253861661338*^9}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["\<\ Converting usual (DownValue-based) function to a pure function\ \>", "Subsection", CellChangeTimes->{{3.4422437194375362`*^9, 3.4422437388554573`*^9}}, FontWeight->"Plain"], Cell["\<\ Here we define some function of several variables. The first variable is \ completely dummy here : it is held and then discarded.\ \>", "Text", CellChangeTimes->{{3.44224221337192*^9, 3.4422422450074096`*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"ClearAll", "[", "testf", "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"Attributes", "[", "testf", "]"}], "=", RowBox[{"{", "HoldFirst", "}"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"testf", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], ":=", RowBox[{ RowBox[{"z", "^", "2"}], "+", RowBox[{"y", "^", "2"}]}]}], ";"}]}], "Input", CellChangeTimes->{{3.435241647675706*^9, 3.435241705689125*^9}, { 3.4352424050848064`*^9, 3.4352424083194575`*^9}}], Cell["Convert to a pure function :", "Text", CellChangeTimes->{{3.44224225267844*^9, 3.442242259788664*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fp", "=", RowBox[{"ToPureFunction", "[", "testf", "]"}]}]], "Input", CellChangeTimes->{{3.4352417240355053`*^9, 3.4352417441143775`*^9}, { 3.435241830929211*^9, 3.4352418485645695`*^9}}], Cell[BoxData[ RowBox[{"Function", "[", RowBox[{"Null", ",", RowBox[{"testf", "[", "##1", "]"}], ",", RowBox[{"{", "HoldFirst", "}"}]}], "]"}]], "Output", CellChangeTimes->{{3.435241734460496*^9, 3.435241747759619*^9}, { 3.435241827173811*^9, 3.4352418492155056`*^9}, 3.4352420920847344`*^9, 3.435242413046254*^9, 3.442230540417035*^9, 3.4422384604054193`*^9, 3.442241330622589*^9, 3.442243176176365*^9, 3.4422440852735825`*^9, 3.4422441717779694`*^9, 3.4422514820095663`*^9, 3.4422538657672415`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"GetPFAttributes", "[", "fp", "]"}]], "Input", CellChangeTimes->{{3.4352417627611904`*^9, 3.435241787106197*^9}, 3.442240775674613*^9}], Cell[BoxData[ RowBox[{"{", "HoldFirst", "}"}]], "Output", CellChangeTimes->{{3.435241770532365*^9, 3.435241787737104*^9}, 3.4352418524902143`*^9, 3.4352420934366784`*^9, 3.4352424146786013`*^9, 3.44223054709664*^9, 3.4422384670950384`*^9, 3.4422413354996014`*^9, 3.4422431777686543`*^9, 3.4422441747522464`*^9, 3.442251484983843*^9, 3.4422538668387823`*^9}] }, Open ]], Cell["\<\ Since the first argument is passed unevaluated to the function, and then \ ignored (discarded) by the function itself, the stars are not printed :\ \>", "Text", CellChangeTimes->{{3.4422413578817854`*^9, 3.44224140721272*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fp", "[", RowBox[{ RowBox[{"Print", "[", "\"\<**\>\"", "]"}], ",", "2", ",", "3"}], "]"}]], "Input", CellChangeTimes->{{3.4352423083857603`*^9, 3.435242310639*^9}, { 3.4352424184640446`*^9, 3.435242433736005*^9}}], Cell[BoxData["13"], "Output", CellChangeTimes->{ 3.4352423110796337`*^9, {3.435242415710085*^9, 3.4352424352481794`*^9}, 3.442238469408365*^9, 3.4422413376526976`*^9, 3.4422431792107277`*^9, 3.4422441756535425`*^9, 3.442251486475989*^9, 3.4422538679904385`*^9}] }, Open ]], Cell["We now clear all attributes of < fp > :", "Text", CellChangeTimes->{{3.4422414175475807`*^9, 3.442241438307432*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fp1", "=", RowBox[{"ClearPFAttributes", "[", "fp", "]"}]}]], "Input", CellChangeTimes->{{3.4352423623233185`*^9, 3.4352423737898064`*^9}, 3.4422407975260334`*^9}], Cell[BoxData[ RowBox[{ RowBox[{"testf", "[", "##1", "]"}], "&"}]], "Output", CellChangeTimes->{3.4352423742604833`*^9, 3.435242441447093*^9, 3.442238473704542*^9, 3.4422413389044976`*^9, 3.442241443304618*^9, 3.442243180913176*^9, 3.442244176795184*^9, 3.442251488078293*^9, 3.4422538691020365`*^9}] }, Open ]], Cell["Now the stars get printed :", "Text", CellChangeTimes->{{3.4422414443761587`*^9, 3.4422414518669295`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fp1", "[", RowBox[{ RowBox[{"Print", "[", "\"\<**\>\"", "]"}], ",", "2", ",", "3"}], "]"}]], "Input", CellChangeTimes->{3.435242447575906*^9}], Cell[BoxData["\<\"**\"\>"], "Print", CellChangeTimes->{3.435242447856309*^9, 3.4422385115089025`*^9, 3.442241340466744*^9, 3.442241457164547*^9, 3.4422431821950192`*^9, 3.4422441778066387`*^9, 3.4422514901612883`*^9, 3.442253871355277*^9}], Cell[BoxData["13"], "Output", CellChangeTimes->{3.435242447916395*^9, 3.4422385115389457`*^9, 3.442241340496787*^9, 3.4422414571945906`*^9, 3.4422431822050333`*^9, 3.442244177846696*^9, 3.442251490181317*^9, 3.442253871355277*^9}] }, Open ]], Cell["We now add a listable attribute :", "Text", CellChangeTimes->{{3.4422415050133505`*^9, 3.442241515768816*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fp2", "=", RowBox[{"SetPFAttributes", "[", RowBox[{"fp", ",", RowBox[{"{", "Listable", "}"}]}], "]"}]}]], "Input", CellChangeTimes->{{3.435242460474453*^9, 3.4352424940527363`*^9}, 3.4422407600621634`*^9}], Cell[BoxData[ RowBox[{"Function", "[", RowBox[{"Null", ",", RowBox[{"testf", "[", "##1", "]"}], ",", RowBox[{"{", RowBox[{"HoldFirst", ",", "Listable"}], "}"}]}], "]"}]], "Output", CellChangeTimes->{3.4352424951443057`*^9, 3.442238515074029*^9, 3.4422414613205233`*^9, 3.442243183366704*^9, 3.442244179018381*^9, 3.442251492244283*^9, 3.4422538725469904`*^9}] }, Open ]], Cell["\<\ We are wrong with the number of arguments here, but we can see that \ Listability works and HoldFirst also works (no printing) :\ \>", "Text", CellChangeTimes->{{3.4422415203353825`*^9, 3.4422415765261807`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fp2", "[", RowBox[{ RowBox[{"Print", "[", "\"\<**\>\"", "]"}], ",", RowBox[{"{", RowBox[{"2", ",", "3"}], "}"}]}], "]"}]], "Input", CellChangeTimes->{{3.4352425080128098`*^9, 3.4352425081930685`*^9}, { 3.442241470403584*^9, 3.4422414738184943`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{"testf", "[", RowBox[{ RowBox[{"Print", "[", "\<\"**\"\>", "]"}], ",", "2"}], "]"}], ",", RowBox[{"testf", "[", RowBox[{ RowBox[{"Print", "[", "\<\"**\"\>", "]"}], ",", "3"}], "]"}]}], "}"}]], "Output", CellChangeTimes->{ 3.43524250851353*^9, 3.4422385166763325`*^9, {3.4422414652161245`*^9, 3.4422414741990414`*^9}, 3.4422431845484033`*^9, 3.4422441803102384`*^9, 3.4422514955590496`*^9, 3.442253874059165*^9}] }, Open ]], Cell["This time the number of arguments is right :", "Text", CellChangeTimes->{{3.442241592549221*^9, 3.442241609633787*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fp2", "[", RowBox[{ RowBox[{"Print", "[", "\"\<**\>\"", "]"}], ",", "1", ",", RowBox[{"{", RowBox[{"2", ",", "3"}], "}"}]}], "]"}]], "Input", CellChangeTimes->{{3.442241588493389*^9, 3.442241588753763*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{"5", ",", "10"}], "}"}]], "Output", CellChangeTimes->{3.4422415891643534`*^9, 3.4422417243787823`*^9, 3.442243185619944*^9, 3.4422441813417215`*^9, 3.4422514971313105`*^9, 3.4422538750305614`*^9}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["Some attributes can not be set for a pure function", "Subsection", CellChangeTimes->{{3.442244418212325*^9, 3.442244430960656*^9}}, FontWeight->"Plain"], Cell["\<\ This is how we could simulate the MapThread operation with our functions :\ \>", "Text", CellChangeTimes->{{3.4422418923603277`*^9, 3.442241921101656*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"ClearAll", "[", RowBox[{"a", ",", "b", ",", "c", ",", "d", ",", "ourMapThread", ",", "g"}], "]"}], ";"}]], "Input", CellChangeTimes->{{3.4422515072758975`*^9, 3.4422515362876143`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"ourMapThread", "[", RowBox[{"f_", ",", "args_List"}], "]"}], ":=", RowBox[{ RowBox[{"SetPFAttributes", "[", RowBox[{ RowBox[{"ToPureFunction", "[", "f", "]"}], ",", "Listable"}], "]"}], "@@", "args"}]}], ";"}]], "Input", CellChangeTimes->{{3.4422417706252813`*^9, 3.442241885951112*^9}}], Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"g", "[", RowBox[{"x_", ",", "y_"}], "]"}], ":=", RowBox[{"x", "^", "y"}]}], ";"}]], "Input", CellChangeTimes->{{3.44224175496276*^9, 3.44224176647932*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"ourMapThread", "[", RowBox[{"g", ",", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{"a", ",", "b"}], "}"}], ",", RowBox[{"{", RowBox[{"c", ",", "d"}], "}"}]}], "}"}]}], "]"}]], "Input", CellChangeTimes->{{3.442241939127576*^9, 3.442241951795792*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{ SuperscriptBox["a", "c"], ",", SuperscriptBox["b", "d"]}], "}"}]], "Output", CellChangeTimes->{ 3.4422419524567423`*^9, 3.442243189124984*^9, 3.4422441855477695`*^9, { 3.442251501918194*^9, 3.442251538711099*^9}, 3.442253880748784*^9}] }, Open ]], Cell["We can do a little benchmark with Times :", "Text", CellChangeTimes->{{3.442243252626294*^9, 3.44224327264508*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"(", RowBox[{"prod1", "=", RowBox[{"ourMapThread", "[", RowBox[{"Times", ",", RowBox[{"{", RowBox[{ RowBox[{"Range", "[", "10000", "]"}], ",", RowBox[{"Range", "[", "10000", "]"}]}], "}"}]}], "]"}]}], ")"}], "//", "Short"}], "//", "Timing"}]], "Input", CellChangeTimes->{{3.4422426163113184`*^9, 3.4422426460641007`*^9}, { 3.4422432032553024`*^9, 3.4422432132697024`*^9}, {3.442243250493227*^9, 3.442243288978566*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"ToPureFunction", "::", "\<\"nopass\"\>"}], RowBox[{ ":", " "}], "\<\"Warning: the following attributes: \ \\!\\({NumericFunction, OneIdentity, Protected}\\) could not be passed\\nto a \ pure function\"\>"}]], "Message", "MSG", CellChangeTimes->{3.4422441884018736`*^9, 3.4422515444293213`*^9, 3.4422538828417935`*^9}], Cell[BoxData[ RowBox[{"{", RowBox[{"0.039999999999999994`", ",", TagBox[ RowBox[{"{", RowBox[{"1", ",", "4", ",", "9", ",", RowBox[{"\[LeftSkeleton]", "9994", "\[RightSkeleton]"}], ",", "99960004", ",", "99980001", ",", "100000000"}], "}"}], Short]}], "}"}]], "Output", CellChangeTimes->{ 3.4422426479167647`*^9, {3.442243190446885*^9, 3.442243235892232*^9}, 3.4422432896094737`*^9, 3.442244188542075*^9, 3.4422515445294657`*^9, 3.442253882921909*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"(", RowBox[{"prod2", " ", "=", " ", RowBox[{"MapThread", "[", RowBox[{"Times", ",", RowBox[{"{", RowBox[{ RowBox[{"Range", "[", "10000", "]"}], ",", RowBox[{"Range", "[", "10000", "]"}]}], "}"}]}], "]"}]}], ")"}], "//", "Short"}], "//", "Timing"}]], "Input", CellChangeTimes->{{3.4422432156531296`*^9, 3.4422432278206253`*^9}, { 3.442243293024384*^9, 3.4422432988727937`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{"0.01999999999999998`", ",", TagBox[ RowBox[{"{", RowBox[{"1", ",", "4", ",", "9", ",", RowBox[{"\[LeftSkeleton]", "9994", "\[RightSkeleton]"}], ",", "99960004", ",", "99980001", ",", "100000000"}], "}"}], Short]}], "}"}]], "Output", CellChangeTimes->{{3.442243228721922*^9, 3.4422432338092365`*^9}, 3.4422432996038446`*^9, 3.4422515474035983`*^9, 3.442253885305336*^9}] }, Open ]], Cell["\<\ Our version is somewhat slower than built - in (which is expected of course) \ .\ \>", "Text", CellChangeTimes->{{3.4422433123621902`*^9, 3.442243346080675*^9}, { 3.442244202361947*^9, 3.4422442045450864`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"prod1", "===", "prod2"}]], "Input", CellChangeTimes->{{3.442243304290584*^9, 3.442243307505206*^9}}], Cell[BoxData["True"], "Output", CellChangeTimes->{3.4422433078256674`*^9, 3.4422515512891855`*^9, 3.44225388690764*^9}] }, Open ]], Cell["\<\ Note that a warning message has been generated. This is because not all \ attributes of a symbol can be passed to a pure function. \ \>", "Text", CellChangeTimes->{{3.4422433935389166`*^9, 3.442243429640829*^9}, { 3.442244207038672*^9, 3.442244226726982*^9}, {3.4422442638403487`*^9, 3.4422443330298386`*^9}, 3.442251557728445*^9}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"Attributes", "[", "Times", "]"}]], "Input", CellChangeTimes->{{3.4422443357136974`*^9, 3.4422443400399184`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{ "Flat", ",", "Listable", ",", "NumericFunction", ",", "OneIdentity", ",", "Orderless", ",", "Protected"}], "}"}]], "Output", CellChangeTimes->{3.4422443404805517`*^9, 3.442251570697093*^9, 3.4422538907531695`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"SetPFAttributes", "[", RowBox[{ RowBox[{"ToPureFunction", "[", "Times", "]"}], ",", "HoldFirst"}], "]"}]], "Input", CellChangeTimes->{{3.442244273504245*^9, 3.442244276138032*^9}, { 3.442251598416952*^9, 3.4422516012009554`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"ToPureFunction", "::", "\<\"nopass\"\>"}], RowBox[{ ":", " "}], "\<\"Warning: the following attributes: \ \\!\\({NumericFunction, OneIdentity, Protected}\\) could not be passed\\nto a \ pure function\"\>"}]], "Message", "MSG", CellChangeTimes->{3.442244276568651*^9, 3.4422515715182734`*^9, 3.442251601791805*^9, 3.442253892065056*^9}], Cell[BoxData[ RowBox[{"Function", "[", RowBox[{"Null", ",", RowBox[{"Times", "[", "##1", "]"}], ",", RowBox[{"{", RowBox[{"Flat", ",", "HoldFirst", ",", "Listable", ",", "Orderless"}], "}"}]}], "]"}]], "Output", CellChangeTimes->{3.442244276638752*^9, 3.442251571548317*^9, 3.442251601821848*^9, 3.4422538920750704`*^9}] }, Open ]], Cell["\<\ Some attributes that are legitimate for symbols are not legitimate for pure \ functions :\ \>", "Text", CellChangeTimes->{{3.4422433935389166`*^9, 3.442243429640829*^9}, { 3.442244207038672*^9, 3.442244226726982*^9}, {3.4422442638403487`*^9, 3.442244266173704*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"SetPFAttributes", "[", RowBox[{"fp2", ",", "Locked"}], "]"}]], "Input", CellChangeTimes->{{3.4422433550736065`*^9, 3.4422433811611185`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"SetPFAttributes", "::", "\<\"unknwn\"\>"}], RowBox[{ ":", " "}], "\<\"Can not set unknown (or invalid for a pure function) \ attribute(s) \\!\\({Locked}\\) \"\>"}]], "Message", "MSG", CellChangeTimes->{3.442243381631795*^9, 3.4422442317542114`*^9, 3.442251610714635*^9, 3.442253893787533*^9}], Cell[BoxData[ RowBox[{"SetPFAttributes", "[", RowBox[{ RowBox[{"Function", "[", RowBox[{"Null", ",", RowBox[{"testf", "[", "##1", "]"}], ",", RowBox[{"{", RowBox[{"HoldFirst", ",", "Listable"}], "}"}]}], "]"}], ",", "Locked"}], "]"}]], "Output", CellChangeTimes->{3.4422433816918817`*^9, 3.4422442317642255`*^9, 3.442251610754693*^9, 3.4422538938275905`*^9}] }, Open ]], Cell[TextData[{ "The set of legitimate attributes is a bit wider than what you can find in \ official ", StyleBox["Mathematica", FontSlant->"Italic"], " Help, since we can use an undocumented construct ", StyleBox["Function[Null, body[##], attrs]", FontSlant->"Italic"], " (we actually do use this all the time in this package), for which also ", StyleBox["HoldFirst, HoldRest", FontSlant->"Italic"], ", ", StyleBox["NHoldFirst", FontSlant->"Italic"], " and ", StyleBox["NHoldRest", FontSlant->"Italic"], " make sense :" }], "Text", CellChangeTimes->{{3.4422434404964385`*^9, 3.4422435661371007`*^9}, { 3.442251620518733*^9, 3.4422516292012177`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"SetPFAttributes", "[", RowBox[{"fp2", ",", "NHoldRest"}], "]"}]], "Input", CellChangeTimes->{{3.442243534892173*^9, 3.4422435383871984`*^9}}], Cell[BoxData[ RowBox[{"Function", "[", RowBox[{"Null", ",", RowBox[{"testf", "[", "##1", "]"}], ",", RowBox[{"{", RowBox[{"HoldFirst", ",", "Listable", ",", "NHoldRest"}], "}"}]}], "]"}]], "Output", CellChangeTimes->{3.4422435389179616`*^9, 3.442251652124179*^9, 3.4422538956201677`*^9}] }, Open ]], Cell[TextData[{ "Removing the ", StyleBox["HoldFirst", FontSlant->"Italic"], " attribute with ", StyleBox["RemovePFAttributes", FontSlant->"Italic"], " (previously we used ", StyleBox["ClearPFAttributes", FontSlant->"Italic"], ", which clears all attributes. This one can be more specific) :" }], "Text", CellChangeTimes->{{3.442242078447909*^9, 3.44224208318472*^9}, { 3.442242117514083*^9, 3.442242179503219*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fp3", "=", RowBox[{"RemovePFAttributes", "[", RowBox[{"fp2", ",", RowBox[{"{", "HoldFirst", "}"}]}], "]"}]}]], "Input", CellChangeTimes->{{3.435242529433611*^9, 3.435242548501029*^9}, 3.44224081645325*^9}], Cell[BoxData[ RowBox[{"Function", "[", RowBox[{"Null", ",", RowBox[{"testf", "[", "##1", "]"}], ",", RowBox[{"{", "Listable", "}"}]}], "]"}]], "Output", CellChangeTimes->{{3.4352425410102577`*^9, 3.435242548881576*^9}, 3.442238519730725*^9, 3.4422419656356926`*^9, 3.442251687114493*^9, 3.442253896791853*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fp3", "[", RowBox[{ RowBox[{"Print", "[", "\"\<**\>\"", "]"}], ",", "2", ",", "3"}], "]"}]], "Input", CellChangeTimes->{{3.4352425555010943`*^9, 3.4352425555511665`*^9}}], Cell[BoxData["\<\"**\"\>"], "Print", CellChangeTimes->{3.4352425580647807`*^9, 3.442238521613432*^9, 3.4422419756400785`*^9, 3.44225168874684*^9, 3.4422538979635377`*^9}], Cell[BoxData["13"], "Output", CellChangeTimes->{3.4352425581348815`*^9, 3.442238521633461*^9, 3.4422419756701217`*^9, 3.442251688756854*^9, 3.4422538980035954`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fp3", "[", RowBox[{ RowBox[{"Print", "[", "\"\<**\>\"", "]"}], ",", "2", ",", RowBox[{"{", RowBox[{"1", ",", "2", ",", "3"}], "}"}]}], "]"}]], "Input", CellChangeTimes->{{3.4422385256592493`*^9, 3.442238561390629*^9}}], Cell[BoxData["\<\"**\"\>"], "Print", CellChangeTimes->{3.442238561821248*^9, 3.4422419798761697`*^9, 3.442251689648136*^9, 3.442253899295453*^9}], Cell[BoxData[ RowBox[{"{", RowBox[{"5", ",", "8", ",", "13"}], "}"}]], "Output", CellChangeTimes->{3.44223856187132*^9, 3.442241979906213*^9, 3.4422516896681647`*^9, 3.442253899305467*^9}] }, Open ]], Cell["We remove the last remaining attribute now :", "Text", CellChangeTimes->{{3.4422420311699266`*^9, 3.4422420511586685`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fp4", " ", "=", " ", RowBox[{"RemovePFAttributes", "[", RowBox[{"fp3", ",", "Listable"}], "]"}]}]], "Input", CellChangeTimes->{{3.4422419843526063`*^9, 3.442242023398752*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"testf", "[", "##1", "]"}], "&"}]], "Output", CellChangeTimes->{{3.442242019152646*^9, 3.442242023699184*^9}, 3.4422516911603107`*^9, 3.4422539003970366`*^9}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["A bit more interesting example", "Subsection", CellChangeTimes->{{3.44224664724752*^9, 3.442246647557966*^9}, { 3.4422502188031645`*^9, 3.442250234726061*^9}}, FontWeight->"Plain"], Cell["\<\ Here is a higher - order function < processLists >, which takes another list \ - processing function, and a list of sublists of equal length. \ \>", "Text", CellChangeTimes->{{3.442250241245435*^9, 3.4422503322563024`*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"Clear", "[", "processLists", "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{ RowBox[{"processLists", "[", RowBox[{"processingF_Function", ",", RowBox[{"lists", ":", RowBox[{"{", "__List", "}"}]}]}], "]"}], "/;", RowBox[{"Equal", "@@", RowBox[{"Map", "[", RowBox[{"Length", ",", "lists"}], "]"}]}]}], ":=", RowBox[{"processingF", "@@", "lists"}]}], ";"}]}], "Input", CellChangeTimes->{{3.442246670080352*^9, 3.442246799576558*^9}, { 3.442249725754195*^9, 3.442249729789998*^9}, {3.442249898782998*^9, 3.442249938600253*^9}}], Cell["\<\ We now want to use our function to compare the sub - lists for equality \ element - by - element. We try :\ \>", "Text", CellChangeTimes->{{3.4422503370131426`*^9, 3.4422503682079983`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"processLists", "[", RowBox[{ RowBox[{ RowBox[{"Equal", "[", "##", "]"}], "&"}], ",", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{"1", ",", "2", ",", "3"}], "}"}], ",", RowBox[{"{", RowBox[{"1", ",", "2", ",", "4"}], "}"}]}], "}"}]}], "]"}]], "Input", CellChangeTimes->{{3.4422497516814766`*^9, 3.4422497776588306`*^9}, { 3.4422498461072545`*^9, 3.442249867928632*^9}}], Cell[BoxData["False"], "Output", CellChangeTimes->{3.4422498684193373`*^9, 3.4422499069447346`*^9, 3.4422499401224413`*^9, 3.4422516990116*^9, 3.442253904462883*^9}] }, Open ]], Cell["\<\ The Equal function is not Listable, and so we just confirm the fact that the \ lists are not equal as a whole.\ \>", "Text", CellChangeTimes->{{3.442250375468438*^9, 3.4422504156061535`*^9}, { 3.442251043098443*^9, 3.4422510459926047`*^9}, {3.442251707393653*^9, 3.442251708084646*^9}}], Cell["\<\ Suppose now that we require that the processing function is Listable. There \ are two possible types of behavior : either < processLists > complains upon \ receiving a non - Listable function : \ \>", "Text", CellChangeTimes->{{3.4422504221856146`*^9, 3.4422504301270337`*^9}, { 3.4422505026913757`*^9, 3.4422505912286863`*^9}, {3.442251066171621*^9, 3.442251068084371*^9}, {3.4422517199617248`*^9, 3.442251722815829*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"ClearAll", "[", "processLists", "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"processLists", "::", "nolstble"}], "=", "\"\\""}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{ RowBox[{"processLists", "[", RowBox[{"processingF_Function", ",", RowBox[{"lists", ":", RowBox[{"{", "__List", "}"}]}]}], "]"}], "/;", RowBox[{ RowBox[{"Equal", "@@", RowBox[{"Map", "[", RowBox[{"Length", ",", "lists"}], "]"}]}], "&&", RowBox[{"MemberQ", "[", RowBox[{ RowBox[{"GetPFAttributes", "[", "processingF", "]"}], ",", "Listable"}], "]"}]}]}], ":=", RowBox[{"processingF", "@@", "lists"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"processLists", "[", RowBox[{"processingF_Function", ",", RowBox[{"{", "__List", "}"}]}], "]"}], ":=", RowBox[{"\"\\"", "/;", RowBox[{"Message", "[", RowBox[{"processLists", "::", "nolstble"}], "]"}]}]}], ";"}]}], "Input", CellChangeTimes->{{3.442249954773509*^9, 3.442250088305518*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"processLists", "[", RowBox[{ RowBox[{ RowBox[{"Equal", "[", "##", "]"}], "&"}], ",", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{"1", ",", "2", ",", "3"}], "}"}], ",", RowBox[{"{", RowBox[{"1", ",", "2", ",", "4"}], "}"}]}], "}"}]}], "]"}]], "Input"], Cell[BoxData[ RowBox[{ RowBox[{"processLists", "::", "\<\"nolstble\"\>"}], RowBox[{ ":", " "}], "\<\"The passed processing function is not Listable\"\>"}]], \ "Message", "MSG", CellChangeTimes->{{3.4422500745657616`*^9, 3.442250089897808*^9}, 3.4422505973074274`*^9, 3.44225173831812*^9, 3.442253907787664*^9}], Cell[BoxData[ RowBox[{"processLists", "[", RowBox[{ RowBox[{ RowBox[{"Equal", "[", "##1", "]"}], "&"}], ",", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{"1", ",", "2", ",", "3"}], "}"}], ",", RowBox[{"{", RowBox[{"1", ",", "2", ",", "4"}], "}"}]}], "}"}]}], "]"}]], "Output", CellChangeTimes->{3.442250089897808*^9, 3.442250597317442*^9, 3.442251738348163*^9, 3.442253907817707*^9}] }, Open ]], Cell["\<\ Or, it makes it Listable by creating a Listable copy of the original function \ :\ \>", "Text", CellChangeTimes->{{3.4422505987595153`*^9, 3.4422506270401807`*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"ClearAll", "[", "processLists", "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{ RowBox[{"processLists", "[", RowBox[{"processingF_Function", ",", "lists_"}], "]"}], "/;", RowBox[{"!", RowBox[{"MemberQ", "[", RowBox[{ RowBox[{"GetPFAttributes", "[", "processingF", "]"}], ",", "Listable"}], "]"}]}]}], ":=", "\[IndentingNewLine]", RowBox[{"processLists", "[", RowBox[{ RowBox[{"SetPFAttributes", "[", RowBox[{"processingF", ",", "Listable"}], "]"}], ",", "lists"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{ RowBox[{"processLists", "[", RowBox[{"processingF_Function", ",", RowBox[{"lists", ":", RowBox[{"{", "__List", "}"}]}]}], "]"}], "/;", RowBox[{"Equal", "@@", RowBox[{"Map", "[", RowBox[{"Length", ",", "lists"}], "]"}]}]}], ":=", RowBox[{"processingF", "@@", "lists"}]}], ";"}]}], "Input", CellChangeTimes->{{3.44225010496948*^9, 3.442250197372349*^9}, 3.442251094241984*^9}], Cell["Now everything works as we want it :", "Text", CellChangeTimes->{{3.442251005063752*^9, 3.4422510131253443`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"processLists", "[", RowBox[{ RowBox[{ RowBox[{"Equal", "[", "##", "]"}], "&"}], ",", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{"1", ",", "2", ",", "3"}], "}"}], ",", RowBox[{"{", RowBox[{"1", ",", "2", ",", "4"}], "}"}]}], "}"}]}], "]"}]], "Input"], Cell[BoxData[ RowBox[{"{", RowBox[{"True", ",", "True", ",", "False"}], "}"}]], "Output", CellChangeTimes->{3.4422502061649923`*^9, 3.4422506336196413`*^9, 3.4422517481422462`*^9, 3.4422539106017103`*^9}] }, Open ]], Cell["\<\ In fact, in the latter case we may remove the restriction of the passed \ function to be a pure function, by adding another definition to \ :\ \>", "Text", CellChangeTimes->{{3.4422508096026926`*^9, 3.4422508346086493`*^9}, { 3.4422511015925536`*^9, 3.4422511265584526`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"processLists", "[", RowBox[{"processingF_Symbol", ",", "lists_"}], "]"}], ":=", RowBox[{"processLists", "[", RowBox[{ RowBox[{"ToPureFunction", "[", "processingF", "]"}], ",", "lists"}], "]"}]}], ";"}]], "Input", CellChangeTimes->{{3.4422508543069744`*^9, 3.442250882016819*^9}}], Cell["Now we can call it like this :", "Text", CellChangeTimes->{{3.442250883989656*^9, 3.442250890949664*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"processLists", "[", RowBox[{"Equal", ",", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{"1", ",", "2", ",", "3"}], "}"}], ",", RowBox[{"{", RowBox[{"1", ",", "2", ",", "4"}], "}"}]}], "}"}]}], "]"}]], "Input", CellChangeTimes->{3.442250896888203*^9}], Cell[BoxData[ RowBox[{ RowBox[{"ToPureFunction", "::", "\<\"nopass\"\>"}], RowBox[{ ":", " "}], "\<\"Warning: the following attributes: \\!\\({Protected}\\) \ could not be passed\\nto a pure function\"\>"}]], "Message", "MSG", CellChangeTimes->{3.4422508982501616`*^9, 3.442251765346986*^9, 3.4422539123642445`*^9}], Cell[BoxData[ RowBox[{"{", RowBox[{"True", ",", "True", ",", "False"}], "}"}]], "Output", CellChangeTimes->{3.442250898300234*^9, 3.4422517653770285`*^9, 3.442253912394288*^9}] }, Open ]], Cell["\<\ The warning is to alert that not all attributes could be passed to a pure \ function wrapper. In this case, it does not matter.\ \>", "Text", CellChangeTimes->{{3.4422509183490624`*^9, 3.4422509724067936`*^9}}], Cell["\<\ Anyway, we got what we wanted. Even if this example is somewhat contrived, it \ shows a situation where the functionality of the package can actually be \ useful.\ \>", "Text", CellChangeTimes->{{3.442250635352133*^9, 3.4422507239295006`*^9}, 3.4422507826339135`*^9, {3.442250979306715*^9, 3.442250989881922*^9}}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["Summary", "Section", CellChangeTimes->{{3.442245198193883*^9, 3.442245201218232*^9}}, FontWeight->"Plain"], Cell[TextData[{ "The functions of this package allow to change (set, clear, remove) \ attributes for a given pure function. To add some number of attributes to a \ pure function, use ", StyleBox["SetPFAttributes", FontWeight->"Bold", FontSlant->"Italic"], ". To remove a given attribute or set of attributes, use ", StyleBox["RemovePFAttributes", FontWeight->"Bold", FontSlant->"Italic"], ". To clear all currently set attributes for the pure function, use ", StyleBox["ClearPFAttributes", FontWeight->"Bold", FontSlant->"Italic"], ". To learn which attribute does a pure function have, use ", StyleBox["GetPFAttributes", FontWeight->"Bold", FontSlant->"Italic"], ". To convert a normal (", StyleBox["DownValue", FontSlant->"Italic"], " - based) function to (or, rather, wrap into) a pure function, call ", StyleBox["ToPureFunction", FontWeight->"Bold", FontSlant->"Italic"], ". In this case, only those attributes of the original function that make \ sense in the pure function' s setting, will be set, and for the rest (if \ any), the warning message is generated. \n \n In all cases, the resulting \ pure function is a copy - no action is performed on the original pure \ function (this is not possible in general since a pure function is an \ expression and does not represent an L - value)" }], "Text", CellChangeTimes->{{3.4422452170810413`*^9, 3.442245665185384*^9}, { 3.442251825874019*^9, 3.4422518263046384`*^9}}] }, Open ]] }, Open ]] }, WindowSize->{1016, 651}, WindowMargins->{{0, Automatic}, {Automatic, 0}}, ShowSelection->True, Magnification->1.5, FrontEndVersion->"6.0 for Microsoft Windows (32-bit) (April 28, 2007)", StyleDefinitions->"Default.nb" ] (* End of Notebook Content *) (* Internal cache information *) (*CellTagsOutline CellTagsIndex->{} *) (*CellTagsIndex CellTagsIndex->{} *) (*NotebookFileOutline Notebook[{ Cell[CellGroupData[{ Cell[590, 23, 550, 10, 117, "Subtitle"], Cell[CellGroupData[{ Cell[1165, 37, 278, 9, 156, "Subsection"], Cell[1446, 48, 147, 2, 41, "Subsubsection"], Cell[1596, 52, 411, 9, 31, "Subsubsection"] }, Open ]], Cell[CellGroupData[{ Cell[2044, 66, 121, 2, 105, "Section"], Cell[2168, 70, 1455, 23, 286, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[3660, 98, 123, 2, 105, "Section"], Cell[CellGroupData[{ Cell[3808, 104, 117, 2, 54, "Subsection"], Cell[3928, 108, 244, 7, 42, "Text"], Cell[4175, 117, 530, 14, 125, "Input"], Cell[4708, 133, 102, 1, 41, "Text"], Cell[4813, 136, 209, 3, 43, "Input"], Cell[CellGroupData[{ Cell[5047, 143, 138, 2, 43, "Input"], Cell[5188, 147, 2092, 58, 99, "Print"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[7329, 211, 163, 2, 54, "Subsection"], Cell[7495, 215, 111, 1, 41, "Text"], Cell[7609, 218, 280, 7, 43, "Input"], Cell[7892, 227, 104, 1, 41, "Text"], Cell[CellGroupData[{ Cell[8021, 232, 165, 3, 43, "Input"], Cell[8189, 237, 529, 9, 42, "Output"] }, Open ]], Cell[8733, 249, 130, 1, 41, "Text"], Cell[CellGroupData[{ Cell[8888, 254, 431, 9, 43, "Input"], Cell[9322, 265, 761, 13, 48, "Output"] }, Open ]], Cell[10098, 281, 108, 1, 41, "Text"], Cell[CellGroupData[{ Cell[10231, 286, 245, 4, 43, "Input"], Cell[10479, 292, 538, 10, 48, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[11054, 307, 168, 3, 43, "Input"], Cell[11225, 312, 366, 7, 33, "Message"], Cell[11594, 321, 431, 11, 48, "Output"] }, Open ]], Cell[12040, 335, 131, 1, 41, "Text"], Cell[CellGroupData[{ Cell[12196, 340, 261, 4, 43, "Input"], Cell[12460, 346, 483, 9, 48, "Output"] }, Open ]], Cell[12958, 358, 186, 4, 41, "Text"], Cell[CellGroupData[{ Cell[13169, 366, 98, 1, 43, "Input"], Cell[13270, 369, 344, 8, 48, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[13651, 382, 136, 2, 43, "Input"], Cell[13790, 386, 424, 7, 42, "Output"] }, Open ]], Cell[14229, 396, 300, 7, 41, "Text"], Cell[CellGroupData[{ Cell[14554, 407, 211, 5, 43, "Input"], Cell[14768, 414, 480, 10, 33, "Message"], Cell[15251, 426, 444, 10, 48, "Output"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[15744, 442, 160, 3, 54, "Subsection"], Cell[15907, 447, 151, 3, 41, "Text"], Cell[CellGroupData[{ Cell[16083, 454, 169, 4, 43, "Input"], Cell[16255, 460, 306, 6, 45, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[16598, 471, 166, 3, 43, "Input"], Cell[16767, 476, 283, 5, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[17087, 486, 245, 6, 43, "Input"], Cell[17335, 494, 429, 9, 48, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[17801, 508, 135, 2, 43, "Input"], Cell[17939, 512, 295, 5, 42, "Output"] }, Open ]], Cell[18249, 520, 118, 1, 41, "Text"], Cell[CellGroupData[{ Cell[18392, 525, 225, 5, 43, "Input"], Cell[18620, 532, 310, 6, 45, "Output"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[18979, 544, 184, 4, 54, "Subsection"], Cell[19166, 550, 220, 4, 66, "Text"], Cell[19389, 556, 560, 15, 98, "Input"], Cell[19952, 573, 109, 1, 41, "Text"], Cell[CellGroupData[{ Cell[20086, 578, 216, 4, 43, "Input"], Cell[20305, 584, 527, 9, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[20869, 598, 163, 3, 43, "Input"], Cell[21035, 603, 375, 6, 42, "Output"] }, Open ]], Cell[21425, 612, 237, 4, 66, "Text"], Cell[CellGroupData[{ Cell[21687, 620, 249, 6, 43, "Input"], Cell[21939, 628, 272, 4, 42, "Output"] }, Open ]], Cell[22226, 635, 123, 1, 41, "Text"], Cell[CellGroupData[{ Cell[22374, 640, 194, 4, 43, "Input"], Cell[22571, 646, 312, 6, 42, "Output"] }, Open ]], Cell[22898, 655, 113, 1, 41, "Text"], Cell[CellGroupData[{ Cell[23036, 660, 176, 5, 43, "Input"], Cell[23215, 667, 246, 3, 32, "Print"], Cell[23464, 672, 237, 3, 42, "Output"] }, Open ]], Cell[23716, 678, 117, 1, 41, "Text"], Cell[CellGroupData[{ Cell[23858, 683, 246, 6, 43, "Input"], Cell[24107, 691, 383, 8, 42, "Output"] }, Open ]], Cell[24505, 702, 222, 4, 66, "Text"], Cell[CellGroupData[{ Cell[24752, 710, 291, 7, 43, "Input"], Cell[25046, 719, 500, 13, 42, "Output"] }, Open ]], Cell[25561, 735, 126, 1, 41, "Text"], Cell[CellGroupData[{ Cell[25712, 740, 246, 6, 43, "Input"], Cell[25961, 748, 242, 5, 42, "Output"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[26252, 759, 160, 2, 54, "Subsection"], Cell[26415, 763, 166, 3, 41, "Text"], Cell[26584, 768, 228, 5, 43, "Input"], Cell[26815, 775, 365, 10, 71, "Input"], Cell[27183, 787, 212, 6, 43, "Input"], Cell[CellGroupData[{ Cell[27420, 797, 309, 9, 43, "Input"], Cell[27732, 808, 288, 7, 48, "Output"] }, Open ]], Cell[28035, 818, 122, 1, 41, "Text"], Cell[CellGroupData[{ Cell[28182, 823, 528, 14, 71, "Input"], Cell[28713, 839, 362, 8, 88, "Message"], Cell[29078, 849, 498, 12, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[29613, 866, 484, 13, 71, "Input"], Cell[30100, 881, 446, 10, 42, "Output"] }, Open ]], Cell[30561, 894, 223, 5, 41, "Text"], Cell[CellGroupData[{ Cell[30809, 903, 125, 2, 43, "Input"], Cell[30937, 907, 123, 2, 42, "Output"] }, Open ]], Cell[31075, 912, 349, 6, 66, "Text"], Cell[CellGroupData[{ Cell[31449, 922, 137, 2, 43, "Input"], Cell[31589, 926, 263, 6, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[31889, 937, 265, 6, 43, "Input"], Cell[32157, 945, 380, 8, 88, "Message"], Cell[32540, 955, 346, 8, 42, "Output"] }, Open ]], Cell[32901, 966, 282, 6, 41, "Text"], Cell[CellGroupData[{ Cell[33208, 976, 168, 3, 43, "Input"], Cell[33379, 981, 336, 7, 33, "Message"], Cell[33718, 990, 396, 10, 42, "Output"] }, Open ]], Cell[34129, 1003, 674, 20, 90, "Text"], Cell[CellGroupData[{ Cell[34828, 1027, 169, 3, 43, "Input"], Cell[35000, 1032, 311, 8, 42, "Output"] }, Open ]], Cell[35326, 1043, 431, 13, 66, "Text"], Cell[CellGroupData[{ Cell[35782, 1060, 246, 6, 43, "Input"], Cell[36031, 1068, 330, 7, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[36398, 1080, 204, 5, 43, "Input"], Cell[36605, 1087, 174, 2, 32, "Print"], Cell[36782, 1091, 168, 2, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[36987, 1098, 258, 6, 43, "Input"], Cell[37248, 1106, 149, 2, 32, "Print"], Cell[37400, 1110, 196, 4, 42, "Output"] }, Open ]], Cell[37611, 1117, 130, 1, 41, "Text"], Cell[CellGroupData[{ Cell[37766, 1122, 207, 4, 43, "Input"], Cell[37976, 1128, 197, 4, 42, "Output"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[38222, 1138, 190, 3, 54, "Subsection"], Cell[38415, 1143, 234, 4, 66, "Text"], Cell[38652, 1149, 635, 16, 98, "Input"], Cell[39290, 1167, 200, 4, 41, "Text"], Cell[CellGroupData[{ Cell[39515, 1175, 438, 12, 43, "Input"], Cell[39956, 1189, 169, 2, 42, "Output"] }, Open ]], Cell[40140, 1194, 303, 6, 41, "Text"], Cell[40446, 1202, 438, 7, 66, "Text"], Cell[40887, 1211, 1189, 33, 206, "Input"], Cell[CellGroupData[{ Cell[42101, 1248, 317, 10, 43, "Input"], Cell[42421, 1260, 323, 7, 33, "Message"], Cell[42747, 1269, 430, 12, 42, "Output"] }, Open ]], Cell[43192, 1284, 175, 4, 41, "Text"], Cell[43370, 1290, 1095, 31, 179, "Input"], Cell[44468, 1323, 120, 1, 41, "Text"], Cell[CellGroupData[{ Cell[44613, 1328, 317, 10, 43, "Input"], Cell[44933, 1340, 212, 4, 42, "Output"] }, Open ]], Cell[45160, 1347, 303, 6, 66, "Text"], Cell[45466, 1355, 351, 9, 71, "Input"], Cell[45820, 1366, 112, 1, 41, "Text"], Cell[CellGroupData[{ Cell[45957, 1371, 309, 9, 43, "Input"], Cell[46269, 1382, 328, 7, 61, "Message"], Cell[46600, 1391, 184, 4, 42, "Output"] }, Open ]], Cell[46799, 1398, 221, 4, 41, "Text"], Cell[47023, 1404, 328, 6, 66, "Text"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[47400, 1416, 114, 2, 105, "Section"], Cell[47517, 1420, 1466, 34, 241, "Text"] }, Open ]] }, Open ]] } ] *) (* End of internal cache information *)