title: CS450 layout: true author: Tiago Cogumbreiro lecture: 6 abstract: Functions as data-structures, currying sep: ☽ <img id="logo" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iYSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgMTI0LjggNTkuNiI+PGRlZnM+PHN0eWxlPi5ie2ZpbGw6IzAwNWE4Yjt9PC9zdHlsZT48L2RlZnM+PHBhdGggY2xhc3M9ImIiIGQ9Ik02LjQ1LDQzLjkxYzEuMzgsMCwyLjUyLS4zMiwzLjQtLjk3LC44OC0uNjUsMS4zMi0xLjUyLDEuMzItMi42MSwwLS43OC0uMjctMS40Ny0uODEtMi4wNS0uNTQtLjU4LTEuMjUtLjk1LTIuMTUtMS4wOSwxLjY5LS41MSwyLjUzLTEuNTIsMi41My0zLjAzLDAtLjk1LS4zNy0xLjcxLTEuMTItMi4yNy0uNzUtLjU2LTEuODEtLjg0LTMuMTktLjg0SC4yOHYxMi44NUg2LjQ1Wm0tMy4zOC0xMC41NGgyLjk0Yy42NSwwLDEuMTQsLjExLDEuNDYsLjMyLC4zMiwuMjEsLjQ5LC41NywuNDksMS4wNiwwLC45My0uNjUsMS40LTEuOTUsMS40SDMuMDd2LTIuNzdoMFptMCw1LjAxaDIuOTdjMS40OSwwLDIuMjQsLjU0LDIuMjQsMS42MnMtLjc1LDEuNi0yLjI0LDEuNkgzLjA3di0zLjIxaDBabTEwLjcsNC40M2MuOTIsLjkyLDIuMDcsMS4zOSwzLjQ1LDEuMzlzMi41OS0uNDUsMy40OS0xLjM0Yy44OS0uODksMS4zNC0yLjA3LDEuMzQtMy41NHMtLjQ1LTIuNjItMS4zNS0zLjUyYy0uOS0uOS0yLjA2LTEuMzUtMy40OC0xLjM1cy0yLjU2LC40NS0zLjQ3LDEuMzVjLS45MSwuOS0xLjM2LDIuMDctMS4zNiwzLjUycy40NiwyLjU3LDEuMzgsMy41aDBabTMuNDUtLjY5Yy0uNjYsMC0xLjE4LS4yNC0xLjU1LS43MS0uMzctLjQ3LS41Ni0xLjE2LS41Ni0yLjA3cy4xOS0xLjYxLC41Ni0yLjFjLjM3LS41LC44OS0uNzQsMS41NS0uNzRzMS4xOCwuMjUsMS41NSwuNzRjLjM3LC41LC41NiwxLjIsLjU2LDIuMXMtLjE5LDEuNTktLjU2LDIuMDdjLS4zNywuNDctLjg5LC43MS0xLjU1LC43MWgwWm03LjI2LDEuMzJjLjgsLjQ4LDEuNzUsLjcyLDIuODQsLjcyLDEuMzIsMCwyLjM2LS4yNywzLjEyLS44MiwuNzYtLjU0LDEuMTQtMS4yOCwxLjE0LTIuMjEsMC0xLjUxLTEuMDUtMi40Ni0zLjE2LTIuODZsLTEuMjctLjI0Yy0uNDktLjA5LS44Mi0uMTktMS0uMzItLjE4LS4xMy0uMjctLjMyLS4yNy0uNThzLjExLS40OCwuMzQtLjY0Yy4yMy0uMTYsLjU1LS4yNCwuOTYtLjI0LC45MiwwLDEuNTQsLjQzLDEuODUsMS4yOWwyLjE1LS45N2MtLjI1LS41OC0uNy0xLjA3LTEuMzctMS40OS0uNjctLjQyLTEuNS0uNjItMi41MS0uNjItMS4yMSwwLTIuMTcsLjI2LTIuODgsLjc5LS43MSwuNTMtMS4wNiwxLjIzLTEuMDYsMi4xMXMuMjQsMS40OCwuNzMsMS44OWMuNDgsLjQyLDEuMjYsLjczLDIuMzIsLjk0bDEuMywuMjZjLjQyLC4wOSwuNzEsLjIxLC44OCwuMzYsLjE3LC4xNSwuMjYsLjM2LC4yNiwuNjJzLS4xMywuNDktLjM4LC42NmMtLjI1LC4xNy0uNTksLjI2LTEuMDIsLjI2LS43NywwLTEuMjktLjE3LTEuNTYtLjUxLS4yOC0uMzYtLjQ2LS43LS41My0xLjAzbC0yLjM3LC43NWMuMTgsLjgsLjY4LDEuNDMsMS40OCwxLjkxaDBabTkuOTgtLjJjLjQyLC40NCwuOTksLjY2LDEuNzEsLjY2aDMuMDd2LTIuMDdoLTEuOThjLS4yOCwwLS40OS0uMDYtLjYyLS4xOS0uMTMtLjEzLS4xOS0uMzMtLjE5LS42MnYtNC4zMWgyLjM5di0xLjk4aC0yLjM5di0yLjg4aC0yLjYxdjIuODhoLTEuOTN2MS45OGgxLjkzdjQuNzljMCwuNzIsLjIxLDEuMywuNjIsMS43NGgwWm02Ljc2LS40M2MuOTIsLjkyLDIuMDcsMS4zOSwzLjQ1LDEuMzlzMi41OS0uNDUsMy40OS0xLjM0Yy44OS0uODksMS4zNC0yLjA3LDEuMzQtMy41NHMtLjQ1LTIuNjItMS4zNS0zLjUyYy0uOS0uOS0yLjA2LTEuMzUtMy40OC0xLjM1cy0yLjU2LC40NS0zLjQ3LDEuMzVjLS45MSwuOS0xLjM2LDIuMDctMS4zNiwzLjUycy40NiwyLjU3LDEuMzgsMy41aDBabTMuNDUtLjY5Yy0uNjYsMC0xLjE4LS4yNC0xLjU1LS43MS0uMzctLjQ3LS41Ni0xLjE2LS41Ni0yLjA3cy4xOS0xLjYxLC41Ni0yLjFjLjM3LS41LC44OS0uNzQsMS41NS0uNzRzMS4xOCwuMjUsMS41NSwuNzRjLjM3LC41LC41NiwxLjIsLjU2LDIuMXMtLjE5LDEuNTktLjU2LDIuMDdjLS4zNywuNDctLjg5LC43MS0xLjU1LC43MWgwWm05LjE2LDEuNzh2LTQuMzVjMC0xLjE1LC4yLTEuOTcsLjYxLTIuNDYsLjI3LS4zMywuNjgtLjUsMS4yMy0uNSwuOTgsMCwxLjQ3LC41OCwxLjQ3LDEuNzN2NS41OGgyLjYxdi02LjE1YzAtMS4wNS0uMjUtMS44Ny0uNzYtMi40NC0uNTEtLjU4LTEuMjYtLjg2LTIuMjctLjg2LTEuMjgsMC0yLjI3LC41Ni0yLjk2LDEuNjl2LTEuNDFoLTIuNTN2OS4xOGgyLjYxWiIvPjxwYXRoIGNsYXNzPSJiIiBkPSJNMS44NiwyNS43YzEuMDUsLjk1LDIuNDQsMS40Myw0LjE5LDEuNDNzMy4xLS40OCw0LjE3LTEuNDNjMS4wNi0uOTUsMS42LTIuMjUsMS42LTMuODd2LTcuODRoLTIuNzl2Ny40YzAsMi4yNC0uOTksMy4zNi0yLjk3LDMuMzYtLjk4LDAtMS43Mi0uMjgtMi4yMi0uODUtLjUtLjU3LS43NS0xLjQtLjc1LTIuNTF2LTcuNEguMjl2Ny44NGMwLDEuNjMsLjUyLDIuOTIsMS41NywzLjg3aDBabTE1LjUsMS4xNHYtMTAuNDZsMy41NCwxMC40NmgyLjQ4bDMuNTgtMTAuNDh2MTAuNDhoMi43OVYxMy45OWgtNC40MWwtMi4xNSw2LjI2Yy0uNCwxLjIxLS43MywyLjEyLS45NywyLjc0LS4yNC0uNjEtLjU3LTEuNTItLjk3LTIuNzRsLTIuMTEtNi4yNmgtNC41N3YxMi44NWgyLjc5Wm0xNS4xMy0uNDRjLjU1LC40OSwxLjI0LC43MywyLjA3LC43MywxLjM4LDAsMi40My0uNTQsMy4xNC0xLjYzLC4xLC44OSwuNjUsMS4zNCwxLjY1LDEuMzRoMnYtMS45OGgtLjgxYy0uMjUsMC0uNC0uMDMtLjQ2LS4wOS0uMDYtLjA2LS4wOS0uMjEtLjA5LS40NnYtMy4zNmMwLTEuMTctLjM1LTIuMDYtMS4wNi0yLjY2LS43LS42LTEuNzItLjktMy4wNC0uOS0xLjI1LDAtMi4yNywuMjgtMy4wNiwuODMtLjc5LC41NS0xLjIyLDEuMjEtMS4yOSwxLjk4bDIuMzUsLjUxYy4yMy0uOTcsLjkxLTEuNDUsMi4wMi0xLjQ1LDEsMCwxLjUxLC40MiwxLjUxLDEuMjd2LjM1Yy0uODksLjA5LTEuNjcsLjIxLTIuMzIsLjM2LS42NSwuMTUtMS4yNSwuMzYtMS43OCwuNjMtLjUzLC4yNy0uOTQsLjYyLTEuMjIsMS4wNi0uMjgsLjQ0LS40MywuOTYtLjQ0LDEuNTYsMCwuNzgsLjI4LDEuNDIsLjgzLDEuOTFoMFptNC4zOS0xLjczYy0uMzcsLjM3LS44MywuNTUtMS4zOCwuNTUtLjgsMC0xLjE5LS4zMy0xLjE5LS45OSwwLS41NCwuMjYtLjkzLC43Ny0xLjE3LC41MS0uMjQsMS4zLS40MywyLjM1LS41N3YuNTljMCwuNy0uMTgsMS4yMy0uNTUsMS42aDBabTYuMzgsMS43MWMuOCwuNDgsMS43NSwuNzIsMi44NCwuNzIsMS4zMiwwLDIuMzYtLjI3LDMuMTItLjgyLC43Ni0uNTQsMS4xNC0xLjI4LDEuMTQtMi4yMSwwLTEuNTEtMS4wNS0yLjQ2LTMuMTYtMi44NmwtMS4yNy0uMjRjLS40OS0uMDktLjgyLS4xOS0xLS4zMi0uMTgtLjEzLS4yNy0uMzItLjI3LS41OHMuMTEtLjQ4LC4zNC0uNjRjLjIzLS4xNiwuNTUtLjI0LC45Ni0uMjQsLjkyLDAsMS41NCwuNDMsMS44NSwxLjI5bDIuMTUtLjk3Yy0uMjQtLjU4LS43LTEuMDctMS4zNy0xLjQ5LS42Ny0uNDItMS41LS42Mi0yLjUxLS42Mi0xLjIxLDAtMi4xNywuMjYtMi44OCwuNzktLjcxLC41My0xLjA3LDEuMjMtMS4wNywyLjExcy4yNCwxLjQ3LC43MiwxLjg5Yy40OCwuNDIsMS4yNiwuNzMsMi4zMiwuOTRsMS4zLC4yNmMuNDIsLjA5LC43MSwuMjEsLjg4LC4zNiwuMTcsLjE1LC4yNiwuMzYsLjI2LC42MnMtLjEzLC40OS0uMzgsLjY2Yy0uMjUsLjE3LS41OSwuMjYtMS4wMiwuMjYtLjc3LDAtMS4yOS0uMTctMS41Ni0uNTEtLjI4LS4zNS0uNDYtLjctLjUzLTEuMDNsLTIuMzcsLjc1Yy4xOCwuOCwuNjgsMS40MywxLjQ4LDEuOTFoMFptOS40NSwwYy44LC40OCwxLjc1LC43MiwyLjg0LC43MiwxLjMyLDAsMi4zNi0uMjcsMy4xMi0uODIsLjc2LS41NCwxLjE0LTEuMjgsMS4xNC0yLjIxLDAtMS41MS0xLjA1LTIuNDYtMy4xNi0yLjg2bC0xLjI3LS4yNGMtLjQ5LS4wOS0uODItLjE5LTEtLjMyLS4xOC0uMTMtLjI3LS4zMi0uMjctLjU4cy4xMS0uNDgsLjM0LS42NGMuMjMtLjE2LC41NS0uMjQsLjk2LS4yNCwuOTIsMCwxLjU0LC40MywxLjg1LDEuMjlsMi4xNS0uOTdjLS4yNC0uNTgtLjctMS4wNy0xLjM3LTEuNDktLjY3LS40Mi0xLjUtLjYyLTIuNTEtLjYyLTEuMjEsMC0yLjE3LC4yNi0yLjg4LC43OS0uNzEsLjUzLTEuMDcsMS4yMy0xLjA3LDIuMTFzLjI0LDEuNDcsLjczLDEuODljLjQ4LC40MiwxLjI2LC43MywyLjMyLC45NGwxLjMsLjI2Yy40MiwuMDksLjcxLC4yMSwuODgsLjM2LC4xNywuMTUsLjI2LC4zNiwuMjYsLjYycy0uMTMsLjQ5LS4zOCwuNjZjLS4yNSwuMTctLjU5LC4yNi0xLjAyLC4yNi0uNzcsMC0xLjI5LS4xNy0xLjU2LS41MS0uMjgtLjM1LS40Ni0uNy0uNTMtMS4wM2wtMi4zNywuNzVjLjE4LC44LC42OCwxLjQzLDEuNDgsMS45MWgwWiIvPjxwYXRoIGNsYXNzPSJiIiBkPSJNMTIzLjU2LDM3Ljk1YzAtNS40NCwwLTEwLjg5LDAtMTYuMzMsMC0uNTMtLjAyLTEuMDYtLjA0LTEuNi0uMDUtMS4xNS0uMjItMi4yOS0uNDctMy40MS0xLjY2LTcuNDEtNy4yMy0xMy4zNi0xNC41LTE1LjUtMS42Ni0uNDktMy4zNi0uNzgtNS4xLS44Mi0uNTQtLjAxLTEuMDgsMC0xLjYyLDBoLTM2LjU2di40YzAsNy4xOCwwLDE0LjM2LDAsMjEuNTQsMCw1LjI1LDAsMTAuNTEsMCwxNS43NiwwLC42NiwuMDQsMS4zMywuMDgsMS45OSwuMDksMS4zMiwuMzQsMi42MSwuNjksMy44OCwxLjc4LDYuNDYsNi43MSwxMS43OCwxMywxNC4wNiwyLjM4LC44Niw0LjgzLDEuMjYsNy4zNiwxLjI2LDUuMiwwLDEwLjQsMCwxNS42LDAsLjg0LDAsMS42Ny0uMDQsMi41MS0uMDksMS4wNC0uMDYsMi4wNi0uMjQsMy4wNy0uNDksNS4yMi0xLjMyLDkuMzUtNC4yMSwxMi4zOS04LjY0LDEuNjgtMi40NCwyLjc0LTUuMTQsMy4yNy04LjA2LC4yMy0xLjMsLjMyLTIuNjEsLjMyLTMuOTNoMFptLTIwLjAxLTIzLjc5Yy0uMDMsLjg3LS4xMiwxLjcyLS4zNCwyLjU2LS4zLDEuMTktLjgzLDIuMjYtMS42OCwzLjE1LS42OCwuNzItMS41LDEuMjQtMi40MSwxLjYzLTEuMDcsLjQ2LTIuMTksLjczLTMuMzUsLjg5LTEuMjYsLjE4LTIuNTMsLjIyLTMuODEsLjIxLS42MywwLTEuMjYsMC0xLjg4LDBoLS4zMVY4LjE5YzAtLjYzLC4wMS0xLjI2LC4xMS0xLjg4LC4wMi0uMTEsLjA0LS4yMiwuMDYtLjMzLC4wOC0uNDQsLjMzLS43MiwuNzgtLjg1LC41NS0uMTYsMS4xMi0uMjksMS42OS0uMzQsLjY3LS4wNiwxLjM0LS4xLDIuMDEtLjEsMS4zMiwwLDIuNjIsLjE4LDMuODgsLjY0LDIuNDQsLjg4LDQuMDMsMi41OCw0Ljc5LDUuMDYsLjM4LDEuMjMsLjUsMi40OSwuNDUsMy43N2gwWm0yLjM5LDIwLjQ4Yy4zMiwxLjMyLC40MSwyLjY3LC4zMyw0LjAyLS4wNiwxLjExLS4yNCwyLjItLjYxLDMuMjUtLjg3LDIuNDgtMi41NSw0LjItNC45NCw1LjI1LTEuMDEsLjQ0LTIuMDcsLjczLTMuMTYsLjg5LS45NCwuMTUtMS44OSwuMjItMi44NCwuMTktLjg3LS4wMy0xLjc0LS4wOS0yLjU4LS4zNS0uOTQtLjI5LTEuNTctLjktMS45LTEuODMtLjIzLS42Ni0uMzUtMS4zNS0uNC0yLjA1LS4wNC0uNy0uMDctMS4zOS0uMDctMi4wOSwwLTQuNzUsMC05LjQ5LDAtMTQuMjR2LS40Yy4xMiwwLC4yMS0uMDEsLjI5LS4wMSwxLjEyLDAsMi4yMy0uMDEsMy4zNSwuMDEsMi4wMiwuMDUsNC4wMSwuMjksNS45NSwuODgsLjk5LC4zLDEuOTMsLjcsMi44MSwxLjI1LDEuOTcsMS4yMiwzLjIsMi45NywzLjc1LDUuMjFoMFptMTUuNjQsMy43OWMtLjA0LDQuODQtMS43NCw5LjA3LTUuMDEsMTIuNjQtMi41NywyLjgxLTUuNzIsNC42Ny05LjQyLDUuNThoMGMtLjkxLC4yMy0xLjg0LC40LTIuNzgsLjQ1LS43MSwuMDQtMS40MywuMDktMi4xNCwuMDktNS4zNSwwLTEwLjcsLjAxLTE2LjA1LDAtMy43OCwwLTcuMjYtMS4wNS0xMC40MS0zLjEzLTEuNjgtMS4xMS0zLjE0LTIuNDYtNC40LTQuMDQtMS4wMy0xLjI5LTEuNjMtMi43Ny0xLjg5LTQuNC0uMTgtMS4xMy0uMjItMi4yNi0uMTItMy4zOSwuMS0xLjE2LC4yNC0yLjMyLC4zNi0zLjQ5LC4xMi0xLjExLC4yNS0yLjIyLC4zOS0zLjMzLC4xMy0xLjEsLjI2LTIuMiwuMzktMy4zLC4xMS0uOTYsLjIyLTEuOTIsLjM0LTIuODgsLjExLS45NSwuMjMtMS45LC4zNC0yLjg2LC4xMS0uOTYsLjIzLTEuOTIsLjM0LTIuODgsLjExLS45NSwuMjMtMS45LC4zNC0yLjg2LC4wOC0uNjUsLjE1LTEuMywuMjQtMS45NSwuMDMtLjE5LS4wMy0uMzItLjE4LS40NC0uMzgtLjMtLjc1LS42My0xLjEzLS45My0uMTItLjA5LS4xOC0uMi0uMTgtLjM1LDAtLjg5LDAtMi42NywwLTIuNjd2LS4yN2gyLjQ1di00LjZoLTEuMnMyLjc4LTIuMTcsNC4wOC0zLjE0Yy4xMy0uMSwuMjktLjM0LC4yOS0uNTQtLjAxLS44LDAtMS41NiwwLTIuMzYsMC0uMDgsMC0uMTYsMC0uMjQsLjAyLS4xMSwuMDgtLjE5LC4xOC0uMjIsLjAzLS4wMSwuMDYtLjAyLC4xLS4wMiwuMTQsMCwuMjUsLjA5LC4yNywuMjMsLjAxLC4wOCwwLC4xNiwwLC4yMywwLC44MiwuMDIsMS41NCwwLDIuMzYsMCwuMiwuMTQsLjQ0LC4yNywuNTQsMS4yOSwuOTYsNC4xMSwzLjE0LDQuMTEsMy4xNGgtMS4ydjQuNmgyLjQ2czAsLjI5LDAsLjY5YzAsLjU4LDAsMS42MiwwLDIuMjQsMCwuMTQtLjA1LC4yNC0uMTYsLjM0LS40MSwuMzMtLjgsLjY3LTEuMjEsMS0uMTIsLjA5LS4xNiwuMTktLjE0LC4zNCwuMSwuODcsLjE5LDEuNzMsLjI5LDIuNiwuMSwuODgsLjE5LDEuNzUsLjI4LDIuNjMsLjEsLjg5LC4yLDEuNzksLjI5LDIuNjgsLjA5LC44OCwuMTksMS43NSwuMjgsMi42MywuMSwuODksLjE5LDEuNzksLjI5LDIuNjgsLjEsLjg4LC4xOSwxLjc1LC4yOCwyLjYzLC4xLC45LC4yLDEuOCwuMjksMi43LC4wOSwuODgsLjE5LDEuNzUsLjI4LDIuNjMsLjEsLjg5LC4xOSwxLjc5LC4yOSwyLjY4LC4wOSwuODgsLjE5LDEuNzUsLjI4LDIuNjMsLjEyLDEuMTMsLjE5LDIuMjgsLjQ3LDMuMzksLjA5LC4zNSwuMTksLjcxLC4zMiwxLjA1LC41LDEuMzUsMS40NCwyLjI2LDIuNzgsMi43NiwuNzQsLjI3LDEuNTEsLjQzLDIuMjksLjUyLDEuMTksLjEzLDIuMzgsLjIsMy41OCwuMTUsMS4yNi0uMDUsMi41My0uMSwzLjc5LS4yLDEuODgtLjE2LDMuNzMtLjQ1LDUuNTUtLjkyLC42MS0uMTYsMS4yMS0uMzMsMS44MS0uNTMsMi4xMS0uNyw0LjA4LTEuNjYsNS44Ni0zLDEuOTItMS40NCwzLjQ4LTMuMTksNC41NC01LjM2LC42OC0xLjQxLDEuMDktMi45LDEuMjUtNC40NiwuMi0xLjk3LC4wNC0zLjktLjYtNS43OC0uNzYtMi4yMi0yLjEyLTQtMy45OS01LjQyLTEuNDgtMS4xMi0zLjEyLTEuOTEtNC44Ni0yLjUtLjQ5LS4xNy0xLS4zMS0xLjUtLjQ3LS4wOC0uMDMtLjE2LS4wNS0uMzEtLjA5LC4xMy0uMDcsLjIxLS4xMSwuMjktLjE1LDEuMTctLjU1LDIuMjgtMS4yMSwzLjI5LTIuMDIsMi4zMS0xLjg0LDMuOC00LjE5LDQuMjgtNy4xMiwuNTItMy4xMywuMDMtNi4xLTEuNjItOC44NC0uMS0uMTYtLjIyLS4zNC0uMzYtLjUzLS44My0xLjA2LTIuMjYtMi4zOS0yLjMtMi40NiwuMDgsLjAyLC4xNiwuMDQsLjI0LC4wNyw1LjQxLDEuODksOS4yNiw1LjQ3LDExLjU0LDEwLjczLC42NiwxLjUzLDEuMDgsMy4xMywxLjI5LDQuNzgsLjEsLjc3LC4xNiwxLjU1LC4xNiwyLjMyLC4wMSw1LjgsLjA1LDExLjYxLDAsMTcuNDFoMFpNNzUsMTQuMDRzMS45OCwwLDIuOTgsMGMwLTEuNTUsMC00LjYxLDAtNC42MWgtMi45OHY0LjZoMFptNDIuNDEsNDUuMTR2LTIuNTRoLjk1di0uMzRoLTIuMjh2LjM0aC45NXYyLjU0aC4zOFptMS43LDB2LTIuNDVsLjgzLDIuNDVoLjM0bC44NC0yLjQxdjIuNDFoLjM3di0yLjg4aC0uNTFsLS42OSwyYy0uMDcsLjItLjEyLC4zNi0uMTUsLjQ2LS4wMy0uMDktLjA3LS4yNC0uMTQtLjQzbC0uNjgtMi4wNGgtLjU3djIuODhoLjM3WiIvPjwvc3ZnPg==" height="64" /> .bottom-bar[ {{title}} {{sep}} {{abstract}} {{sep}} Lecture {{lecture}} {{sep}} {{author}} ] --- class: middle # {{title}} ## Structure of Higher Level Languages ### Lecture {{lecture}}: {{abstract}} ### {{author}} --- class: impact # Functions as data-structures ## Exercises --- # Exercise 1 ## What is the output of this program? ```scheme (define x 10) (define (f x) (+ x 20)) (f 30) ``` -- **Output:** 50 Because, parameter `x` shadows the outermost definition. --- # Exercise 2 ## What is the output of this program? ```scheme (define x 10) (define f (lambda (x) (+ x 20))) (f 30) ``` -- **Output:** 50 The code above is **equivalent** to the code below: ``` (define (f x) (+ x 20)) ``` --- # Exercise 3 ## What is the output of this program? ```scheme (define (factory k) (lambda () k)) (factory 10) ``` -- **Output:** `#<procedure>` Although if Racket displayed code, we would get: `(lambda () 10)` ```scheme ((factory 10)) ; Outputs: 10 ``` --- # Exercise 3 ## Step-by-step evaluation ```scheme (factory 10) = ( (lambda (k) (lambda () k)) 10) = ; ^^^^^^^^^^^^^^^^^^^^^^^^^^\______ the value *bound* to factory (lambda () 10) ``` .space-top[ ### Why is factory replaced by a lambda? ] <div markdown class="col-6"> ### User input ```scheme (define (factory k) (lambda () k)) ``` </div> <div markdown class="col-6"> ### Internal representation ```scheme (define factory (lambda (k) (lambda () k))) ``` </div> --- # Exercise 3 ### Looking at function application more closely ```scheme ( (lambda (k) ; <- parameter k (lambda () k)) ; <- body of function 10 ; <- argument ) ; Remove outer lambda and replace each parameter by argument ; (lambda () k) <- body of function ; \___ replace parameter k by argument 10 (lambda () 10) ; <- return value ``` --- class: impact # The abstract syntactic tree (AST) ## Exercises --- # Exercise ## Q1: What is the output of this program? ```scheme (define (f x y) (lambda (b) (cond [b x] [else y]))) (define g (f 1 2)) g ``` -- **Output:** `(lambda (b) (cond [b 1] [else 2]))` .space-top[ ## Q2: How do I call `g` to obtain `1`? ] -- **Solution:** `(g #t)` --- # Implementing a pair with functions alone If we can capture one parameter, then we can also capture two parameter. .alt[**Let us implement a pair-data structure with only functions!**] **[source: SICP 2.1.3](https://sarabander.github.io/sicp/html/2_002e1.xhtml#g_t2_002e1_002e3)** ```scheme (define (pair l r) (lambda (op) ; <- we use a parameter to choose which stored data to return (match op ; if the operation is 'left then return l ['left l] ; if the operation is 'right then return r ['right r]))) ; We now define our accessors (define (pair-left p) (p 'left)) ; `Returns the first element of the pair` (define (pair-right p) (p 'right)) ; `Returns the second element of the pair` (define p (pair 10 20)) ; Same as: `(define (p op) (match op ['left 10] ['right 20])))` (pair-left p) ; `Returns 10` because (pair-left p) -> (p 'left) -> 10 (pair-right p) ; `Returns 20` because (pair-right p) -> (p 'right) -> 20 ``` --- class: impact # Recursion exercise --- # String concatenation ```scheme (define (string-concat l) 'todo) (check-equal? (string-concat (list "Hello" ", " "world" "!")) "Hello, world!") ``` --- # String concatenation (solution) ```scheme (define (string-concat l) (match l [(list) ""] [(cons h l) (string-append h (string-concat l))] )) (check-equal? (string-concat (list "Hello" ", " "world" "!")) "Hello, world!") ``` --- class: impact # Functions as values --- # What is functional programming > Functional programming has different meanings to different people * Avoid mutation * **Using functions as values** * A programming style that encourages recursion and recursive data structures * A programming model that uses *lazy* evaluation (discussed later) --- # First-class functions * **Functions are values:** can be passed as arguments, stored in data structures, bound to variables, ... * **Functions for extension points:** A powerful way to factor out a common functionality --- class: impact # Functions as parameters --- # Functions as parameters ## Monotonic increasing function (for one input) > Function `monotonic?` takes a function `f` as a parameter and a value > `x`, and then checks if `f` increases monotonically for a given `x`. <div class="col-7" markdown=1> ### Example ```scheme #lang racket (define (double n) (* 2 n)) (define (monotonic? f x) (>= (f x) x)) ;; Tests (require rackunit) (check-true (monotonic? double 3)) (check-false (monotonic? (lambda (x) (- x 1)) 3)) ``` </div> <div class="col-5" markdown=1> ### How do we evaluate? ```scheme (monotonic? double 3) ``` -- ```scheme = (>= (`double` 3) 3) = (>= (`(lambda (n) (* 2 n) 3)` 3) = (>= `(* 2 3)` 3) = (>= 6 3) = #t ``` </div> --- # Functions as parameters ## Recursively apply a function n-times > Function `apply-n` takes a function `f` as parameter, a number of times `n`, and some argument `x`, and then recursively calls `(f (f (... (f x))))` an `n`-number of times. ```scheme #lang racket (define (apply-n f n x) (cond [(<= n 0) x] [else (apply-n f (- n 1) (f x))])) ;; Tests (require rackunit) (define double (lambda (x) (* 2 x))) (check-equal? (* 2 (* 2 (* 2 1))) (apply-n double 3 1)) (check-equal? (+ 3 (+ 3 (+ 3 1))) (apply-n (lambda (x) (+ 3 x)) 3 1)) ``` --- # Example `apply-n` ### Let us unfold the following... ```scheme (apply-n double 3 1) ; (<= 3 0) = #f ``` -- ```scheme = (apply-n double (- 3 1) (double 1)) = (apply-n double 2 2) ; (<= 2 0) = #f = (apply-n double (- 2 1) (double 2)) = (apply-n double 1 4) ; (<= 1 0) = #f = (apply-n double (- 1 1) (double 4)) = (apply-n double 0 8) ; (<= 0 0) = #t = 8 ``` --- class: impact # Functions as data-structures --- # Functions as data-structures The following is a function that returns a constant value (returns 3 always): ```scheme (define three:2 (lambda () 3)) (three:2) ; <- We need to call the function to obtain its contents ; Note that we are passing 0 parameters. ``` .space-top[ ## Note the difference... ] The following is a variable binding (not a function!): ```scheme (define three:1 3) ``` .space-top[ Variable `three:1` *evaluates* to the number `3`. ] --- # A factory of constant-return functions We can generalize the procedure by creating a function that returns a new function declaration that returns a given parameter `n `. ```scheme (define (factory n) (lambda () n)) ; <-- calling 'factory' `creates a new function dynamically` ; each new function captures the given 'n', ; which changes according to how it was called (define three:4 (factory 3)) ; <- same as: `(define three:4 (lambda () 3))` (three:4) ; `Returns: 3` (define four:1 (factory 4)) ; <- same as: `(define four:1 (lambda () 4))` (four:1) ; `Returns 4` ``` --- class: impact # Functions in data structures --- # Functions stored in data structures ## "Freeze" one parameter of a function > In this example, a `frozen` data-structure stores a binary-function and the > first argument. Function `apply1` takes a frozen data structure and the second > argument, and applies the stored function to the two arguments. ```scheme (struct frozen (func arg1) #:transparent) (define (apply1 fr arg) `(define func (frozen-func fr))` ; Bind a function to a local variable (define arg1 (frozen-arg1 fr)) `(func arg1 arg)`) ; Call a function bound to a local variable (define frozen-double (frozen `*` 2)) ; Store function '*' in a data structure (define (double x) (apply1 frozen-double x)) (check-equal? (* 2 3) (double 3)) ``` --- # Unfolding `(double 3)` ```scheme (double 3) = (apply1 frozen-double 3) = (apply1 (frozen * 2) 3) = (define fr (frozen * 2)) ((frozen-func fr) (frozen-arg1 fr) 3) = (* 2 3) = 6 ``` --- # Functions stored in data structures ## Apply a list of functions to a value ```scheme #lang racket (define (double n) (* 2 n)) ; A list with two functions: ; * doubles a number ; * increments a number (define p `(list double (lambda (x) (+ x 1)))`) ; Applies each function to a value (define (pipeline funcs value) (match funcs [(list) value] [(cons f funcs) (pipeline funcs (`f` value))])) ; Run the pipeline (check-equal? (+ 1 (double 3)) (pipeline p 3)) ``` --- class:impact # Creating functions dynamically --- # Returning functions > Functions in Racket automatically capture the value of any variable > referred in its body. .col-5[ ### Example ```scheme #lang racket (define (frozen-* `arg1`) (define (get-arg2 arg2) (* `arg1` arg2)) ; Returns a new function ; every time you call frozen-* `get-arg2`) (require rackunit) (define double (frozen-* 2)) (check-equal? (* 2 3) (double 3)) ``` ] .col-7[ ### Evaluating `(frozen-* 2)` ```scheme (frozen-* 2) = (define (get-arg2 arg2) (* 2 arg2)) get-arg2 = (lambda (arg2) (* 2 arg)) ``` ### Evaluating `(double 3)` ```scheme (double 3) = ((frozen-* 2) 3) = ((lambda (arg2) (* 2 arg2)) 3) = (* 2 3) = 6 ``` ] --- class: impact # Currying functions --- # Revisiting "freeze" function .col-6[ ### Freezing binary-function ```scheme (struct frozen (func arg1) #:transparent) (define (apply1 fr arg) (define func (frozen-func fr)) (define arg1 (frozen-arg1 fr)) (func arg1 arg)) (define frozen-double (frozen * 2)) (define (double x) (apply1 frozen-double x)) (check-equal? (* 2 3) (double 3)) ``` ] .col-6[ ### Attempt #1 ```scheme (define (freeze f arg1) (define (get-arg2 arg2) (f arg1 arg2)) get-arg2) (define double (freeze * 2)) (check-equal? (* 2 3) (double 3)) ``` ] .row[] > Our `freeze` function is more general than `freeze-*` and simpler than > `frozen-double`. We abstain from using a data-structure and use Racket's > variable capture capabilities. --- # Generalizing "frozen" binary functions .col-6[ ### Attempt #2 ```scheme (define (freeze f) (define (expect-1 arg1) (define (expect-2 arg2) (f arg1 arg2)) expect-2) expect-1) (define frozen-* (freeze *)) (define double (frozen-* 2)) (check-equal? (* 2 3) (double 3)) ``` ] .col-6[ ### Evaluation ```scheme (define frozen-* (freeze *)) = (define frozen-* (define (expect-1 arg1) (define (expect-2 arg2) (`*` arg1 arg2)) expect-2) expect-1) (define double (frozen-* 2)) = (define double (define (expect-2 arg2) (* `2` arg2)) expect-2) (double 3) = (* 2 `3`) ``` ] --- # Currying functions **Currying** is the general technique of "freezing" functions with multiple parameters. It provides a way of delaying (and caching) the passage of multiple arguments by means of new functions. > A curried function $`\mathrm{curry}_{f,n,a}(x)`$ is a unary function annotated > with an uncurried function $`f`$ arguments $`a`$ and a number of expected arguments $`n`$ that > can be recursively defined as: ```math \mathrm{curry}_{f,n+1,[a_1,\dots,a_n]}(x) = \mathrm{curry}_{f,n,[a_1,\dots,a_n,x]} \\ \ \mathrm{curry}_{f,0,[a_1,\dots,a_n]}(x) = f(a_1, \dots, a_n, x) ``` ```scheme #lang racket (define frozen-* (curry *)) (define double (frozen-* 2)) (require rackunit) (check-equal? (* 2 3) (double 3)) ``` --- # Haskell Curry ## Did you know? .col-6[ * In some programming languages functions are curried by default. Examples include Haskell and ML. * The term currying is named after Haskell Curry, a notable logician who developed combinatory logic and the Curry-Howard correspondence (practical applications include proof assistants). *Haskell was born in Millis, MA (1 hour drive from UMB).* ] .col-6.center[ <img src="data:image/jpeg;base64,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" height="256px" /> .row[] [Source: public domain](http://www-history.mcs.st-andrews.ac.uk/PictDisplay/Curry.html) ] --- # Uncurried functions > All arguments must be provided at call-time, otherwise error. ### Python example ```python def add(l, r): return l + y add(10) *# Traceback (most recent call last): *# File "<stdin>", line 1, in <module> *# TypeError: add() missing 1 required positional argument: 'r' ``` --- # Curried functions > If we provide one argument to a 2-parameters function, the result > is a 1-parameter function that expects the second argument. ### Haskell example ```haskell -- Define addition add x y = x + y -- Define adding 10 to some number add10 = add 10 -- 10 + 30 add10 30 -- 40 ``` --- # Currying in Racket Function `curry` **converts** an uncurried function into a curried function. ```scheme #lang racket *(define curried-add (curry +)) (define add10 (curried-add 10)) (require rackunit) (check-equal? (+ 10 30) (add10 30)) ``` --- # Currying functions **Currying** is the general technique of "freezing" functions with multiple parameters. It provides a way of delaying (and caching) the passage of multiple arguments by means of new functions. > A curried function $`\mathrm{curry}_{f,n,a}(x)`$ is a unary function annotated > with an uncurried function $`f`$ arguments $`a`$ and a number of expected arguments $`n`$ that > can be recursively defined as: ```math \mathrm{curry}_{f,n+1,[a_1,\dots,a_n]}(x) = \mathrm{curry}_{f,n,[a_1,\dots,a_n,x]} \\ \ \mathrm{curry}_{f,0,[a_1,\dots,a_n]}(x) = f(a_1, \dots, a_n, x) ``` --- # Exercise ## What is the output of this program? <div class="col-6" markdown> ### Program ```scheme (define curried-add (lambda (arg1) (lambda (arg2) (+ arg1 arg2)))) (define a (curried-add 10)) (define b (curried-add 20)) a b (a 30) (b 40) ``` </div> -- <div class="col-6" markdown> ### Output ```scheme (lambda (arg2) (+ 10 arg2)) (lambda (arg2) (+ 20 arg2)) 40 60 ``` </div>