Amb amb Evaluator - SICP Comparison Edition" /> 4.3.3   Implementing the <span style="color:green">Amb</span> <span style="color:blue">amb</span> Evaluator - SICP Comparison Edition
Original JavaScript
 Original JavaScript We start the driver loop as usual, by setting up the global environment and passing it as the enclosing environment for the first iteration of driver_loop. const the_global_environment = setup_environment(); driver_loop(the_global_environment);
 Original JavaScript Exercise 4.61 Implement a new construct called if-fail that permits the user to catch the failure of an expression. If-fail takes two expressions. It evaluates the first expression as usual and returns as usual if the evaluation succeeds. If the evaluation fails, however, the value of the second expression is returned, as in the following example: ;;; Amb-Eval input: (if-fail (let ((x (an-element-of '(1 3 5)))) (require (even? x)) x) 'all-odd) ;;; Starting a new problem ;;; Amb-Eval value: all-odd ;;; Amb-Eval input: (if-fail (let ((x (an-element-of '(1 3 5 8)))) (require (even? x)) x) 'all-odd) ;;; Starting a new problem ;;; Amb-Eval value: 8 There is currently no solution available for this exercise. This textbook adaptation is a community effort. Do consider contributing by providing a solution for this exercise, using a Pull Request in Github. Exercise 4.62 We shall horribly abuse the syntax for conditional statements, by implementing a construct of the following form: if (evaluation_succeeds_take) { $statement$ } else { $alternative$ } The construct permits the user to catch the failure of a statement. It evaluates the statement as usual and returns as usual if the evaluation succeeds. If the evaluation fails, however, the given alternative statement is evaluated, as in the following example: amb-evaluate input: if (evaluation_succeeds_take) { const x = an_element_of(list(1, 3, 5)); require(is_even(x)); x; } else { "all odd"; } Starting a new problem amb-evaluate value: "all odd" amb-evaluate input: if (evaluation_succeeds_take) { const x = an_element_of(list(1, 3, 5, 8)); require(is_even(x)); x; } else { "all odd"; } Starting a new problem amb-evaluate value: 8 Implement this construct by extending the amb evaluator. Hint: The function is_amb shows how to abuse the existing JavaScript syntax in order to implement a new syntactic form. There is currently no solution available for this exercise. This textbook adaptation is a community effort. Do consider contributing by providing a solution for this exercise, using a Pull Request in Github.

[1] We chose to implement the lazy evaluator in section 4.2 as a modification of the ordinary metacircular evaluator of section 4.1.1. In contrast, we will base the amb evaluator on the analyzing evaluator of section 4.1.7, because the execution procedures functions in that evaluator provide a convenient framework for implementing backtracking.
[2] We assume that the evaluator supports let (see exercise 4.31), which we have used in our nondeterministic programs.
[3] With this treatment, amb is no longer a name with proper scoping. To avoid confusion, we must refrain from declaring amb as a name in our nondeterministic programs.
[4] We didn't worry about undoing definitions, since we can assume that internal definitions are scanned out (section 4.1.6). didn't worry about undoing declarations, since we assume that a name can't be used prior to the evaluation of its declaration, so its previous value doesn't matter.
4.3.3   Implementing the Amb amb Evaluator