[Maxima] Semantics of "case"
fateman at cs.berkeley.edu
Mon Jan 8 17:17:41 CST 2007
I think the semantics for case can be taken from the lisp case definition.
I think the answers are those interspersed below.
Stavros Macrakis wrote:
>There has been a lot of discussion about the syntax of a Maxima case
>statement. Let's think about the semantics for a second. There are
>==Kind of comparison==
>One is what kind of comparison to use. Is it syntactic equality (=)
>or semantic equality (equal)?
> In the case of operators (the use case
>that has been discussed the most), they come to the same thing. But
> case x of
> 0 => und,
> 1 => und,
>==Evaluation of cases==
>Are the alternatives evaluated, or (implicitly) quoted?
>implicitly quoted -- though as a general rule I think implicit quoting
>gets you into trouble, it seems to make sense here. Any arguments the
>==Result if not handled==
>What if none of the clauses are true, and there is no otherwise
>clause? In "carefree" languages (to invent a term) like Lisp, the
>result is usually to do nothing, or return nil. In "cautious"
>languages (like Ada or I think ML), this is an error. (Let's not even
>talk about case/switch semantics in "careless" languages like C.)
the implementation I provided returns false. Requiring an "otherwise"
clause could be done as a suggestion to the programmer.
(What a cautious programmer would do).
>I perfer the cautious approach because it makes it easy to write
>first-draft code that instead of failing silently on cases that it
>doesn't handle, lets you know there's a problem, e.g.
>inopx(ex):=block([inflag:true],if atom(expr) then false else op(ex))$
> case opx(ex) of
> false => ex
> "+" => ...
> "*" => ...
> "^" => ...
>This will work fine for algebraic expressions, but will just return
>false for sin(x) or a, which is almost never the right result.
>But given the disagreements in other cases about silent failure vs.
>error signalling, I am not sure we will agree on this....
>What about the (common) case where many alteratives are wanted in a branch, e.g.
> case op(x) of
> ["+", "-"] => ...
> case sign(x) of
> [pos, pz, zero] => f(x),
> [neg, nz, zero] => -f(-x),
> [pnz, pn] => analyze(x)
> end case
>This sort of syntax is fine, unless you also want to allow compound
>objects (like lists and sets) in the selectors, e.g.
> case (list) of
>  => ... /* handle empty list */
>  => ... /* special case */
The solution here is to use this:
case () of
[] => ..... matches the empty list only
[] => ..... matches the list  only
>==Order of testing==
>What if more than one branch can match? Do we evaluate them in order?
> case x of
> a => ...
> b => ...
>or the sign(x) example above (where zero is in more than one clause).
>The natural programming interpretation would be to evaluate the
>clauses sequentially, though the natural mathematical interpretation
>might be to consider the order irrelevant, and assume that if two
>cases overlap, it doesn't matter which one you choose. This also
>allows the implementation more freedom. It may also make it easier to
>treat unevaluated case statements (though more on that some other
Yes, but see guarded conditions programming where the order is
(effectively) random: the program must operate correctly regardless of
More information about the Maxima