Warning: foreach() argument must be of type array|object, bool given in /var/www/html/web/app/themes/studypress-core-theme/template-parts/header/mobile-offcanvas.php on line 20

When we defined the evaluation model in section 1.1.3, we said that the first step in evaluating an expression is to evaluate its subexpressions. But we never specified the order in which the subexpressions should be evaluated (e.g., left to right or right to left). When we introduce assignment, the order in which the arguments to a procedure are evaluated can make a difference to the result. Define a simple procedure \(f\) such that evaluating (+ (f 0) ( \(f\) ) ) will return 0 if the arguments to \(+\) are evaluated from left to right but will return 1 if the arguments are evaluated from right to left.

Short Answer

Expert verified
Define \(f\) with a side effect: set a global variable to 1 when no argument is provided. Evaluate \(+ (f 0) (f)\).

Step by step solution

01

Understanding the Problem

The problem states that we need to define a procedure \(f\) such that evaluating \(+ (f 0) (f)\) will yield different results depending on the order of evaluation of the arguments. Specifically, it should return 0 if evaluated left to right, and 1 if evaluated right to left.
02

Define the Function f

To cause a different result based on evaluation order, the function \(f\) must have side effects. We'll use a side effect by assigning a global variable. Define \(f\) as a procedure that changes this global variable's value and returns a specific result. Initially, let's assume \(f(n)\) returns \(n\) and modifies the side effect.
03

Set Up Global Variable

Define a global variable \(result\) initialized to 0. The procedure \(f\) should set \(result\) to a specific value each time it is called without any arguments.
04

Define Function Behavior

Modify \(f\) so that it checks if an argument is provided. If an argument is given, it does not modify the global variable. Without an argument, it sets \(result\) to 1 before returning 0.
05

Checking Evaluation Result

When the expression \(+ (f 0) (f)\) is evaluated left to right, \(f(0)\) returns 0 and does not change \(result\). Therefore, the final result is 0. When evaluated right to left, the first \(f()\) sets \(result\) to 1, influencing the sum to also be 1.

Unlock Step-by-Step Solutions & Ace Your Exams!

  • Full Textbook Solutions

    Get detailed explanations and key concepts

  • Unlimited Al creation

    Al flashcards, explanations, exams and more...

  • Ads-free access

    To over 500 millions flashcards

  • Money-back guarantee

    We refund you if you fail your exam.

Over 30 million students worldwide already upgrade their learning with Vaia!

Key Concepts

These are the key concepts you need to understand to accurately answer the question.

Side Effects
In programming, a side effect is any change of state or observable interaction with the outside world during the execution of a function or expression. Side effects can include modifying a global variable, altering a static local variable, or performing I/O operations like printing to the console or writing to a file.

Side effects are an important concept because they can influence the outcome of a program depending on how and when functions are called. For instance, if a function modifies a global variable, calling it even without using its return value can change the state of the program.

In this exercise, we're using side effects to alter global variables based on the order of expression evaluation. When the function is evaluated, it modifies a global variable, which in turn affects the final outcome of the computation.
Global Variables
Global variables are variables that are defined outside of any function and can be accessed and modified by any function in the program. They are quite versatile but need to be used cautiously since they can lead to unexpected behaviors and bugs if altered unknowingly by different parts of the program.

In the task described, global variables play a critical role. We set up a global variable to track the effect caused by the function’s execution. This global variable is updated based on whether the function was called with or without an argument, influencing the result when evaluating combined expressions.

One advantage of global variables is that they provide a convenient way to keep track of information shared across various functions without needing to pass extra parameters. However, excessive use of global variables can make debugging and maintaining the code more difficult, as any change in one part of the program can potentially affect another seemingly unrelated part.
Procedures in Programming
Procedures, often referred to as functions or subroutines, are a fundamental concept in programming. They allow for code reuse, modular programming, and abstraction. Procedures can take inputs, known as arguments, and can return outputs as a result of their execution.

The exercise showcases how the order of evaluation of procedures can impact the program's output. When defining a procedure, it’s essential to be aware of both its intended return value and any possible side effects that can arise. A function that only returns a value and doesn't cause side effects is considered a pure function, which tends to be easier to reason about.

In programming languages like Scheme or Lisp, evaluation order can significantly impact results, especially when dealing with complex expressions. Understanding and controlling the order in which procedures execute can help in crafting more predictable and reliable code.

One App. One Place for Learning.

All the tools & learning materials you need for study success - in one app.

Get started for free

Most popular questions from this chapter

Memoization (also called tabulation) is a technique that enables a procedure to record, in a local table, values that have previously been computed. This technique can make a vast difference in the performance of a program. A memoized procedure maintains a table in which values of previous calls are stored using as keys the arguments that produced the values. When the memoized procedure is asked to compute a value, it first checks the table to see if the value is already there and, if so, just returns that value. Otherwise, it computes the new value in the ordinary way and stores this in the table. As an example of memoization, recall from section \(1.2 .2\) the exponential process for computing Fibonacci numbers: \(\begin{aligned}(\text { define }(f i b ~ n)& \\\\(\text { cond }((=\mathrm{n})&0) \\ &((=\mathrm{n} 1)&1) \\ &(e l s e(+(f i b(-\mathrm{n} 1))\\\ & &(f i b(-\mathrm{n}&2))))) \end{aligned}\) The memoized version of the same procedure is \(\begin{aligned}&\text { (define memo-fib } \\\&\text { (memoize (lambda ( } \mathrm{n} \text { ) } \\\&\begin{array}{rll}\text { (cond } & ((=\mathrm{n} & 0) & 0) \\ & ((=\mathrm{n} & 1) & 1)\end{array} \\\& & (\text { else (+ (memo-fib (-n 1)) } \\\& & \end{aligned}\) where the memoizer is defined as (define (memoize f) (let ((table (make-table))) (lambda (x) (let ((previously-computed-result (lookup x table))) (or previously-computed-result (let ((result (f x))) (insert! x result table) result)))))) Draw an environment diagram to analyze the computation of (memo-fib 3 ). Explain why memo-fib computes the \(n\)th Fibonacci number in a number of steps proportional to \(n\). Would the scheme still work if we had simply defined memo-fib to be (memoize fib)?

In software-testing applications, it is useful to be able to count the number of times a given procedure is called during the course of a computation. Write a procedure make-monitored that takes as input a procedure, \(f\), that itself takes one input. The result returned by make-monitored is a third procedure, say mf, that keeps track of the number of times it has been called by maintaining an internal counter. If the input to \(\mathrm{mf}\) is the special symbol how-many-calls?, then \(\mathrm{mf}\) returns the value of the counter. If the input is the special symbol reset-count, then \(m f\) resets the counter to zero. For any other input, \(m f\) returns the result of calling \(f\) on that input and increments the counter. For instance, we could make a monitored version of the sqrt procedure: (define s (make-monitored sqrt)) \((\mathrm{s} 100)\) 10 \(\left(\mathrm{~s}^{\prime}\right.\) hou-many-calls?) 1

A famous problem, first raised by R. Hamming, is to enumerate, in ascending order with no repetitions, all positive integers with no prime factors other than 2,3 , or 5 . One obvious way to do this is to simply test each integer in turn to see whether it has any factors other than 2,3 , and 5 . But this is very inefficient, since, as the integers get larger, fewer and fewer of them fit the requirement. As an alternative, let us call the required stream of numbers \(S\) and notice the following facts about it. \- S begins with \(1 .\) \- The elements of (scale-stream S 2) are also elements of S. \- The same is true for (scale-stream \(\mathrm{S} 3\) ) and (scale-stream \(5 \mathrm{~S}\) ). \- These are all the elements of \(\mathrm{S}\). Now all we have to do is combine elements from these sources. For this we define a procedure merge that combines two ordered streams into one ordered result stream, eliminating repetitions: (define (merge s1 s2) (cond ((stream-null? s1) s2) ((stream-nul1? s2) s1) (else (let ( s1car (stream-car s1)) (s2car (stream-car s2))) (cond ((< s1car s2car) (cons-stream s1car (merge (stream-cdr s1) s2))) ((> s1car s2car) (cons-stream s2car (merge s1 (stream-cdr s2)))) (else (cons-stream s1car (merge (stream-cdr s1) Then the required stream may be constructed with merge, as follows: (define \(\mathrm{S}\) (cons-stream 1 (merge \(\langle ? ?\rangle\langle ? ?\rangle)\) ) Fill in the missing expressions in the places marked \(\langle ? ?\rangle\) above.

It is useful to be able to reset a random-number generator to produce a sequence starting from a given value. Design a new rand procedure that is called with an argument that is either the symbol generate or the symbol reset and behaves as follows: (rand 'generate) produces a new random number, ((rand 'reset) (new-value )) resets the internal state variable to the designated \(\langle\) new-value \(\rangle\). Thus, by resetting the state, one can generate repeatable sequences. These are very handy to have when testing and debugging programs that use random numbers.

An accumulator is a procedure that is called repeatedly with a single numeric argument and accumulates its arguments into a sum. Each time it is called, it returns the currently accumulated sum. Write a procedure make-accumulator that generates accumulators, each maintaining an independent sum. The input to make-accumulator should specify the initial value of the sum; for example (define A (make-accumulator 5)) (A 10) 15 (A 10) 25

See all solutions

Recommended explanations on Computer Science Textbooks

View all explanations

What do you think about this solution?

We value your feedback to improve our textbook solutions.

Study anywhere. Anytime. Across all devices.

Sign-up for free