The Perfectly Accurate Calculator (PAC): - Running the code as it stands opens a GUI interface, that has two fields and display/evaluate buttons. The Display button parses the input to the first field and displays the abstract syntax. The Evaluate button evaluates the expression and displays the result in the second field. - The code, as it is given to you, is incomplete. It only evaluates addition of numbers, regardless of the input. Part of Assignment #4 involves integrating your recursive descent parser code into the PAC framwork. If your parser code is less than perfect, you are free to use someone elses. One student has posted their working code to the discussion board. - In general, it is a bad idea to test your code from with the GUI. It allows only one point for probing functionality, and thus obscures concentrated malfunction in the underlying structure. Testing should still be done from within the test suite and interactions interfaces. - Note that the require statements for list.ss and etc.ss still required, as we are no longer using the student language options that automatically include some of the naming abbreviations we are used to. - The PAC is divided into model and view components. The model component involves the underlying guts of the calculator, managing values, formulae, and states. The view component involves interaction with the user. All functions that are part of the model group begin with an 'M-', and the view stuff begins with a 'V-'. This naming convention defines an abstraction barrier. Everything involving the model side of the code uses and is designed to work only M- code and the view stuff only uses V- code. Higher-Order Programming (a.k.a. Functions as Values, Functions as 1st-Class Values) - In procedural languages like C, you can't take construct functions from other functions at run time. In Scheme, and other functional languages, you can do this by simply treated functions like values. This is called higher-order programming. Higher-order programming involves using functions that construct functions. Example: stringlist->string / reverse_list Consider the two list manipulation functions stringlist->string, which takes a list of strings and collapses them, and reverse_list, which takes a list and outputs the list backwards. See the first DEMO for implementation of these functions using the standard method of recursion we have seen so far. Both of these implementations use tail recursion in the same way, with identical function skeletons (after removing the details). So, we can combine the shared structure into a new function, accumulate_list_lr that takes as arguments a starting value (startval), an accumulation operation (accop), and some sort of list (lst) See the second DEMO for a definition of this function. Then, we need only define the specifics for a given operation, pass them to the accumulate_list_lr function. For instance, for the reverse function, we define the accumulation operation to do a simple switch of elements: x y --> cons y x. The startval is simply an empty list, and the lst argument is the list we want to reverse. (See DEMO) The intermediate function resultfun returns the result of the recursive accumulate_list_lr calls. - There are some built-in higher-order functions in Scheme. One notable one is map, which takes a function as an argument and applies it to every element of a list.