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
>several issues.
>
>==Kind of comparison==
>
>One is what kind of comparison to use. Is it syntactic equality (=)
>or semantic equality (equal)?
>
syntactic.
> In the case of operators (the use case
>that has been discussed the most), they come to the same thing. But
>how about:
>
> assume(equal(x,1))$
> case x of
> 0 => und,
> 1 => und,
> 1/(x*(x-1))
> endcase
>
>==Evaluation of cases==
>
>Are the alternatives evaluated, or (implicitly) quoted?
>
implicitly quoted.
> Probably
>implicitly quoted -- though as a general rule I think implicit quoting
>gets you into trouble, it seems to make sense here. Any arguments the
>other way?
>
>==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
> "+" => ...
> "*" => ...
> "^" => ...
> endcase
>
>This will work fine for algebraic expressions, but will just return
>false for sin(x) or a[2], 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....
>
>==Multiple matches==
>
>What about the (common) case where many alteratives are wanted in a branch, e.g.
>
> case op(x) of
> ["+", "-"] => ...
>
>or
>
> 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 */
> [0] => ... /* special case */
> ...
>
The solution here is to use this:
case () of
[[]] => ..... matches the empty list only
[[0]] => ..... matches the list [0] only
>
>==Order of testing==
>
>What if more than one branch can match? Do we evaluate them in order?
>
>Consider
>
> assume(equal(x,a),equal(x,b))$
> 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
>time).
>
>
Yes, but see guarded conditions programming where the order is
(effectively) random: the program must operate correctly regardless of
the order.
RJF