February 16, 200916 yr I am used to using Nested "If" statements in calculated fields, but wonder if there are times when I should use a "Case" statement instead? Is there any general advice as to when to use which, and what are the advantages and disadvantages of each.
February 17, 200916 yr I don't know that there's any big difference between them. I've used Case for years now. I just think it's easier to read, stands out better in the code. The worst is when people use nested IFs, with no spaces between anything. For some reason plug-in developers seem to do this in their example files. Hard to follow, even harder to edit.
February 17, 200916 yr easier to read, stands out better in the code ... Hard to follow, even harder to edit. LOL, that's not a big difference?
February 17, 200916 yr IIRC the Case function stops when the first true expression is evaluated. The If function evaluates all expressions.
February 17, 200916 yr You are right Vaughan. The case here is to use Case and If when it is appropriate. If Case will get you the result then use Case as it will evaluate faster. If you need all the calculation to evaluate then that's a case for If.
February 17, 200916 yr IIRC the Case function stops when the first true expression is evaluated. The If function evaluates all expressions. If Case will get you the result then use Case as it will evaluate faster. If you need all the calculation to evaluate then that's a case for If. I'm unsure where this information comes from (probably prior to vs. 7) but it simply isn't true. BOTH Case() and If() short circuit (stop evaluating when they hit the first true) ever since vs. 7. Speed-wise, they are exactly the same. The ONLY differences are two: If() is two less letters than Case() and Case() allows multiple evaluations whereas If() restricts to two. The benefit of using Case() always is that, if later you change your mind and wish to add a third criteria, you won't have to change from If() to Case() ... you can just slide another test in the middle of it. BTW, AND, NOT and OR short circuit as well. LaRetta Edited February 17, 200916 yr by Guest Added BTW
February 17, 200916 yr Maybe you're right LaRetta - it's a pre-7 thing coming to think of it. I haven't used If() for a very long time, but I do remember Case() being preferred for evaluation efficiency at one point in time.
February 17, 200916 yr Author Answers to this thread seem to have missed that I said *_nested_* If's. So (by using returns in my calculation as shown below, which AFAIK are ignored in calculating the result, but help to make the code easier to read) the following works for me: If(field1="a";"Alpha"; If(field1="b";"Beta"; If(field1="c";"Charlie"; If(field1="d";"Delta"; "result if not identified")))) returning the words shown if field1 contains only a, b. c or d respectively, and the text "result if not identified" if it contains anything else. And, adding more "cases" is just a matter of copy-and-pasting more lines, and remembering to add an extra final ) for each line added. I can't see what the above code does differently or worse than the same thing expressed as a set of "Cases"? I learned this technique back in FMPro 2, and have continued to use it, but keep wondering if there's something that Case can do better?
February 17, 200916 yr Your nested if's as a SINGLE case statement: Case( field1="a";"Alpha"; field1="b";"Beta"; field1="c";"Charlie"; field1="d";"Delta"; "result if not identified" )
February 17, 200916 yr Author So, the "Case" version is really the same, with one "Case(" at the beginning, and no need to balance off the )'s at the end... I have tested and confirmed that both "If" and "Case" stop at the first true if/case, so both seem to work exactly the same! But what are the 'curly braces'{} that I see in the default Case formula for? I think they're what really put me off using Case for so long!
February 17, 200916 yr but I do remember Case() being preferred for evaluation efficiency at one point in time. For evaluation efficiency; I don't think so. But I do think it is true that, prior to vs. 7, If() REQUIRED a default result whereas Case() didn't. So it might be that, in one circumstance (if you had one test in the Case()), it might be quicker - producing null if test failed, whereas If() might have to produce "" for null. But that is pure speculation on my part (and a very weak speculation as that). Update: Now ... you might be talking back in versions prior to 5.5 ... and I don't know anything about those older versions, sorry. Edited February 17, 200916 yr by Guest Added update
February 17, 200916 yr Author "prior to vs. 7, If() REQUIRED a default result whereas Case() didn't." That's what I was remembering as a difference from earlier versions! So, it's not relevant any more. Thanks.
February 17, 200916 yr Could you give an example of "optional parameters" in use... The Case() function requires 2 parameters. Any parameters beyond that are optional. Quite a few other functions have optional parameters, too - see the help for more details.
February 17, 200916 yr What leads you to this conclusion? I was told so by The Shadow. Edited February 17, 200916 yr by Guest Added quote
February 17, 200916 yr For evaluation efficiency; I don't think so. Shawn or Blackwell might enlighten you better here, but filemaker have turned away from RPN.... http://fmforums.com/forum/showtopic.php?tid/176284/tp/0/all/1/ ...somewhat related to a switch of coding language from Pascal to C++ :? --sd
February 17, 200916 yr AND and OR short circuit. Not sure how to test NOT. I test this by using a CF called Looping() with no parameters that simply calls itself does some little math functions but has no exit condition. If Looping() evaluates, I can see it clearly because of the time it takes before the result as FM hits the 10,000 limit in stack size for a recursive function. The expression: 1 OR Looping() evaluates instantly to 1. Looping() OR 1 takes a couple seconds and evaluates to ?. 0 AND Looping() evaluates instantly to 0. Edited February 17, 200916 yr by Guest
February 17, 200916 yr OK, then. I got some confusing results in my own tests, but it turned out it was just data viewer not refreshing properly.
February 17, 200916 yr I believe he also said XOR but I don't have my cut/paste handy to be sure (this was shortly after vs. 7 came out and I doubt it hasn't changed through the versions since then). And I confess, I don't see how AND can short-circuit since it must wait for the second portion (on the right side of the AND) to decide how to evaluate but I just took his word for it. :smile2:
February 17, 200916 yr XOR cannot short-circuit by definition. BTW, neither can NOT, since there is only one proposition to evaluate, so there is nowhere to short-circuit to. AND can short-circuit, because if the first proposition is false, the result must be false.
February 17, 200916 yr Your nested if's as a SINGLE case statement: Case( field1="a";"Alpha"; field1="b";"Beta"; field1="c";"Charlie"; field1="d";"Delta"; "result if not identified" ) Not forgetting 'Choose' (if you can store 'field1' as numbers). Choose( field1; “Not Identified”; “Alpha”; “Beta”; “Charlie”; "Delta" )
February 18, 200916 yr I can't find my doc with the quote from Shawn. I would have sworn he included NOT (but XOR was only a vague assumption on what he said). I'll take your word for it, Michael, and I stand corrected in a probable misquote on NOT and XOR. Thank you! Maybe Shawn will catch this and speak up if he has more to say on it. AND can short-circuit, because if the first proposition is false, the result must be false. Ah, right! I appreciate the clarification! Edited February 18, 200916 yr by Guest Added quote and sentence
February 18, 200916 yr Shawn or Blackwell might enlighten you better here, but filemaker have turned away from RPN.... ...somewhat related to a switch of coding language from Pascal to C++ :? No, the switch from Pascal was earlier, the short-circuiting (and drop of RPN evaluation of calculations) was dropped in version 7. The older versions calculation format used RPN for storage, so all the arguments appear, then the opcode telling the engine what to do with them. This is trivial to write a stack-based executor for, but very difficult to optimize. With FM7, due to the large file-format change, all calculations were being rewritten anyway, so it was an ideal time to store the operation first, then the arguments following it. Besides short-circuiting, this change leads directly to the ability to easily have functions with a variable number of arguments, as well as "magic" functions like Let() that treat their arguments in special ways.
February 18, 200916 yr I can't find my doc with the quote from Shawn. I would have sworn he included NOT (but XOR was only a vague assumption on what he said). I'll take your word for it, Michael, and I stand corrected in a probable misquote on NOT and XOR. Thank you! Maybe Shawn will catch this and speak up if he has more to say on it. Not doesn't short-circuit, what you might be thinking of is that certain operations are transformed into more simple ones. So executing: A xor B If A if true, this transforms into "not B" (internally), while if A is found to be false, it transforms into "(bool) B". This might seem like an odd thing to do, but its efficient and consistent with the way the calculation engine works post FM7. Another example is with Case(), when a false result is seen for a test, the calculation is internally transformed into a shorter Case() statement that is missing the first two arguments (conceptually).
February 18, 200916 yr Thank you for clarifying! And I appreciate the explanation on RPN as well! :smile2:
Create an account or sign in to comment