The conditional if takes three arguments: an antecedent, a consequent, and an alternative. The antecedent is a test expression. It’s evaluated before the consequent or the alternative. If result is nil, the alternative is evaluated and becomes the value of the conditional; otherwise, the consequent is evaluated. Consider a few examples:
(if nil ‘nope ‘yes) => yes (if (eq nil nil) ‘yes ‘nope) => yes ((if (eq nil ‘x) quote pair) (if (eq ‘a ‘b) ‘c ‘d) (if (eq ‘e ‘e) (pair ‘g nil) ‘h)) => (d g)
Notice that the last example contains three conditionals. Since (eq nil ‘x) is nil, the alternative pair of the first conditional is evaluated. As one of our primitives, pair evaluates to itself. The antecedent (eq ‘a ‘b) of the second conditional is also nil. Its alternative ‘d evaluates to the symbol d. So the value of the second conditional is d. The antecedent (eq ‘e ‘e) of the third conditional is not nil. So its consequent (pair ‘g nil) is used. After having resolved the three conditionals, we have the operator pair, the symbol d, and the pair (g). Applying pair to d and (g) gives us the final answer of (d g).
Conditionals are simple and straightforward. Misp’s final construct will appear simple, but is far from straightforward. The final construct is a more general conditional. With it, having a primitive if is redundant. This final construct is a powerful form of goto: it’s a goto which takes arguments. Arguments allow you to give symbols special meanings inside the goto. This potent goto is known as abstraction since arguments abstract (or parameterize) some part of a wrapped expression. Function definition is another name for abstraction. In Misp we’ll use the symbol fn to create abstractions. You must also know that abstraction has the infamous title lambda: the ultimate goto.
Commentary