1. C++ should be fastest since it descends from C and has a great deal of compile-time information about its objects, and (if the program is well designed) does not need a garbage collector. Ocaml should be next, since it has compile-time type checking. Scheme requires run-time checking. Prolog requires support for unification and backtracking, which is perhaps the slowest computation model here. 2. DCG rules are compiled into Horn clauses. 3. The behavior is not well-defined for two reasons. First, C does not specify whether negative numbers are implemented using twos-complement, ones-complement, or signed-magnitude; for example, only on twos-complement machines is ~x == 1-x. Second, arithmetic overflow can occur in either the negation or the addition, and the resulting behavior is undefined. 4. Parentheses are needed to avoid syntactic ambiguity. For example, the following are both valid C and C++ statements with different semantics: if (f (g ())) /* empty statement */; else break; if (f) (g ()); else break; but if you remove the parentheses in question, they'd both look the same: if f (g ()); else break; 5. (let ((x 1)) (+ (let ((x x)) x) x)) The outer 'x' has discontiguous scope because the inner 'x' shadows it. This isn't possible in Prolog, where a logical variable always has scope that extends to the entire containing clause. 6. type 'a bt = Pair of 'a bt * 'a bt | Nonpair of 'a | Null let rec all_pairs = function | [] -> true | Null :: _ -> false | Nonpair _ :: _ -> false | Pair _ :: tail -> all_pairs tail 7. \+ c_keyword(X) would be invoked before X is instantiated, c_keyword(X) would succeed with X bound to, say "auto", and therefore \+ c_keyword(X) would always fail. Hence this grammar rule would always fail. Here's an example use: id([id(foo)], R, C1, []). 8a. mapbt is not tail recursive because its result is passed to cons before mapbt returns. 8b. (eq? bt (id bt)), but this is not true for (mapbt id bt) since the latter returns a copy of bt. 8c. It will cause f to be invoked on the empty list, and will return whatever f returns. For example, (mapbt (lambda (x) 1) '(a)) returns (1) without the change, but with the change it returns (1 . 1). 9. #f (lambda (x) (or x #t)) (list cons) (lambda (x) (list 1 2 x)) #f (lambda (y) y) (lambda (x) (and (car x) (cdr x))) call/cc map (letrec ((p (lambda (f) (f p)))) p)