# Handling output that was returned unevaluated from a function

When evaluating functions, including those described in this post, how do Mathematica users handle values returned from a function that are unevaluated? For example (based on 1):

i[{a_, Longest[b__], c__}] := {"a" -> a, "b" -> {b}, "c" -> {c}} /; Length[{a, b, c}] > 3;
test = {{1, 2}, {1, 2, 3, 4, 5}, {1, 2, 3, 4, 5}};
j=i/@test

(* returns {i[{1, 2}], {"a" -> 1, "b" -> {2, 3, 4}, "c" -> {5}}, {"a" -> 1,  "b" -> {2, 3, 4}, "c" -> {5}}}  *)


So the first element of j is i[{1, 2}] - this is neither the original input {1,2} nor in the form of the rest of the output. Two questions:

a) While it is likely to be application specific, what approaches do others use to handle unevaluated values that are returned?

b) Is there a generic way to detect unevaluated 'returns' for additional parsing ?

My current thought is to use Identity and ReplaceAll to eliminate the 'unwanted' function i:

k=j/.i->Identity
(* returns {{1, 2}, {"a" -> 1, "b" -> {2, 3, 4}, "c" -> {5}}, {"a" -> 1,   "b" -> {2, 3, 4}, "c" -> {5}}}  *)


but this approach requires the name of the function (here i) that was evaluated. Are there any other tricks or approaches to handle this? Am I overlooking benefits to retaining the unevaluated output ?

-

The only "correct way" is to do what is reasonable for your application. Depending on the use/needs, you have a few options (not an exhaustive list):

• If you know your input is all going to be of a certain type (e.g. lists), you can tighten your patterns so that you don't end up with invalid input (or what you call "unevaluated output")

Clear@i1
i1[{a_, Longest[b__], c__}] := {"a" -> a, "b" -> {b}, "c" -> {c}} /; Length[{a, b, c}] > 3;
i1[c : {___}] := "Too short" /; Length[c] <= 3;
i1 /@ test
(* {"Too short", {"a" -> 1, "b" -> {2, 3, 4}, "c" -> {5}}, {"a" -> 1, "b" -> {2, 3, 4}, "c" -> {5}}} *)


Here the assumption is that "Too short" means something to your application... it could very well be Sequence[].

• If you don't know what kind of input will be supplied, you can add a down-value/pattern that acts as a default or a fall through pattern. This is generally a good thing to do.

Clear@i2
i2[{a_, Longest[b__], c__}] := {"a" -> a, "b" -> {b}, "c" -> {c}} /;
Length[{a, b, c}] > 3;
i2[___] := "Too short";
i2 /@ test
(* {"Too short", {"a" -> 1, "b" -> {2, 3, 4},  "c" -> {5}}, {"a" -> 1, "b" -> {2, 3, 4}, "c" -> {5}}} *)

• If you know a priori what type of terms you want or don't want, you can either selectively choose the items or prune the output to get rid of the undesirable terms.

Cases[i /@ test, {__Rule}]
(* {{"a" -> 1, "b" -> {2, 3, 4}, "c" -> {5}}, {"a" -> 1,  "b" -> {2, 3, 4}, "c" -> {5}}} *)

i /@ test /. _i -> Sequence[]
(* {{"a" -> 1, "b" -> {2, 3, 4}, "c" -> {5}}, {"a" -> 1,  "b" -> {2, 3, 4}, "c" -> {5}}} *)


As I said, this is only useful if you have some knowledge of the structure (you often do).

• Throw an error or a message.

Clear@i3
i3::invalid = "Invalid entry!";
i3[{a_, Longest[b__], c__}] := {"a" -> a, "b" -> {b}, "c" -> {c}} /; Length[{a, b, c}] > 3;
i3[___] /; Message[i3 : invalid] := Null;
i3 /@ test


Message::name: Message name i3:invalid is not of the form symbol::name or symbol::name::language. >>

(* {i3[{1, 2}], {"a" -> 1, "b" -> {2, 3, 4}, "c" -> {5}}, {"a" -> 1, "b" -> {2, 3, 4}, "c" -> {5}}} *)

• Do nothing. (The implicit assumption is that you either don't care or a subsequent step will handle it correctly.)

-
Many thanks, I learned a lot. – PlaysDice Feb 4 '14 at 1:25

Perhaps something like ValueQ[i[#]] & /@ test which returns a vector corresponding the the results being "real" might be of use?

-
thanks. ValueQ is a new one for me. According to reference.wolfram.com/mathematica/ref/ValueQ.html Possible Issues, ValueQ returns True in the case where the value passed is outside the limit, so I dont think it will work – PlaysDice Feb 1 '14 at 0:43
@PlaysDice:Yes, I assumed your "unevaluated" meant globally. Perhaps combined with rm-rf's excellent suggestions it might still be of use. – ciao Feb 1 '14 at 0:53