Interesting Matlab puzzle

Here’s a nice little puzzle that came to me from long-time Matlab veteran Andrew Janke:

Without actually running the following code in Matlab, what do you expect its output to be? ‘Yaba’? ‘Daba’? perhaps ‘Doo!’? or maybe it won’t run at all because of a parsing error?

function test
    try
        if (false) or (true)
            disp('Yaba');
        else
            disp('Daba');
        end
    catch
        disp('Doo!');
    end
end

To muddy the waters a bit, do you think that short-circuit evaluation is at work here? or perhaps eager evaluation? or perhaps neither?
Would the results be different if we switched the order of the conditional operands, i.e. (true) or (false) instead of (false) or (true)? if so, how and why?
And does it matter if I used “false” or “10< 9.9” as the “or” conditional?
Are the parentheses around the conditions important? would the results be any different without these parentheses?

In other words, how and why would the results change for the following variants?

        if (false) or (true)     % variant #1
        if (true)  or (false)    % variant #2
        if (true)  or (10< 9.9)  % variant #3
        if  true   or  10< 9.9   % variant #4
        if 10> 9.9 or  10< 9.9   % variant #5

Please post your thoughts in a comment below (expected results and the reason, for the main code snippet above and its variants), and then run the code. You might be surprised at the results, but not less importantly at the reasons. This deceivingly innocuous code snippet leads to interesting insight on Matlab’s parser.

Full marks will go to the first person who posts the correct results and reasoning/interpretation of the variants above (hint: it’s not as trivial as it might look at first glance).

Addendum April 9, 2019: I have now posted my solution/analysis of this puzzle here.

USA visit

I will be travelling in the US (Boston, New York, Baltimore) in May/June 2019. Please let me know (altmany at gmail) if you would like to schedule a meeting or onsite visit for consulting/training, or perhaps just to explore the possibility of my professional assistance to your Matlab programming needs.

Categories: Medium risk of breaking in future versions, Undocumented feature

Tags: ,

Bookmark and SharePrint Print

20 Responses to Interesting Matlab puzzle

  1. braggpeaks says:

    – or is logical OR, thus no parsing error or ‘Doo!’
    – false is interpreted first, so result would be ‘Daba’

    • braggpeaks says:

      hold on, that was way too quick

    • I said that it’s not as trivial as it might look at first glance :-)

    • braggpeaks says:

      So, back from lunch 😉

      The parser seems to interpret “or” different to | and ||, i.e. as a new command. or(true) would then cause an error, but the line is not reached. The same would apply for “and“.

      I guess why it is interpreted differently is the big Q – I have no answer to that 😉

  2. Cris Luengo says:

    This looks like a Python programmer tried writing MATLAB code. OR is a function, not an operator.

    Does MATLAB interpret this as

    if (false), or (true)

    ?

    • So Cris – what would you expect to happen in Matlab with the variants above? (code as-is; switching false<=>true; and without parentheses)

    • Cris Luengo says:

      or(true) and or true both are missing an argument, I would guess. or true is the same as or('true'), it passes a char array as argument. The function needs two arguments. If executed they’d throw an error. So starting with if true would cause the catch to execute.

      I don’t know what happens with the parenthesis around the argument to if, maybe they’re needed to prevent a syntax error because of the missing comma, but this is just a guess.

    • Cris Luengo says:

      Great Sunday morning exercise! I’m curious to see what happens when I type this into MATLAB tonight. :)

  3. Vin says:

    The answer is Doo!

  4. Roger Watt says:

    this one works as expected:

    if (false) || (true)
    etc

    the parsing is:

    if false,
     or(true)
     disp(1)
    else
     disp(2)
    end
  5. Rik Wisselink says:

    Prior to running it, I would have expected the if to error. Then I pasted it into the editor and the lint told me to put a comma after the false. That caused me to believe it saw the false as the complete conditional, which would cause the else to be executed (which seems to be the case when running it).

    I suspect the reason for this stems from the support for a single line if. I suspect Matlab parses everything from the if to the end of the first function call (or of course || or &&) as the conditional.

    %triggers the else branch:
    if (true && false) or (true)
    %  ^. . . . . . .^
    %this is parsed as the conditional (space delimited command)
    if (true && false) or (true)
    %                  ^. . . .^ 
    %This is considered the code to be executed on if, because there is no
    %logical operator there, and the preceding part is a complete command.
    %Removing the parentheses there will not make a difference, as the space is
    %still demarcating the logical statement from the consequence code.

    Replacing the true and if statements by anything that returns those statements does not change the parsing. Removing the parentheses will only change the or() call to be in the char mode, which would then still be missing its second input. Curiously, you can’t enter a false in char mode. If you try with eval to have a char(0) to force a false, an error is returned instead (not enough inputs), as eval seems to crop from char(0) onwards.

  6. Codrut Dan says:

    Hi everyone,

    new here :)

    nice puzzle. I have never used ‘or’ like that, only used function or(A,B), or the || operator. I would have expected error there…so that was my answer :)
    Now I’ll need to review my knowledge on syntax…

  7. Will says:

    Very intriguing puzzle! I never knew that parentheses around the expression immediately following if allowed you to continue with the first line of the statement group without a comma or semicolon. Is this syntactic logic really not documented? I certainly couldn’t find any.

    That behaviour is of course the reason the main puzzle results in Daba, after seeing that the full condition of the if statement is just false. I don’t think that an if statement skipping the block it would execute if true and proceeding to the else block can be described as short-circuit evaluation, but maybe my understanding of execution engine theory falls short here.

    The variants are fun, too.

    In variant #2 we pass the if condition and get to the function call to or (disguised as a binary operator to fool users of more verbose languages than MATLAB) with only one argument – throwing an exception that results in a Doo!

    In variant #3 nothing changes, because of course 10< 9.9 just evaluates to a scalar false which still isn’t an adequate input to the or function. But of course this is just a set up for

    variant #4, which cunningly uses command syntax to pass two character vector arguments to or, each carefully engineered to be three characters long so that we evaluate the equivalent of ’10<‘ | ‘9.9’ which is a valid vector boolean operation. Since none of the characters involved is the null character the result is `[true true true]` so we finally get a `Yaba`.

    Happy April Fools’!

    • Will says:

      Oh dear, seems I was wrong on (at least) two counts above…

      First, the first set of brackets seem to do nothing. I was sure you normally needed a comma after the condition expression, but apparently not?!

      Second, the command in variant #4 still doesn’t qualify as part of the if condition. So after having satisfied the if true condition, first the result of the unsuppressed command or 10< 9.9 is displayed in the command window:

      ans =
        1×3 logical array
         1   1   1

      then ‘Yaba’ is displayed!

  8. Is it cheating if I not only work at MathWorks, but asked the development lead for the MATLAB Front End and Code Analyzer for an answer? Andrew emailed me the same puzzle over the weekend, which I forwarded on to the dev lead. Here’s the scoop:

    For backwards compatibility, space is a valid separator between the expression in the if-condition and the first statement in the body. We don’t want to encourage users to write more such code because we realize this can be very confusing, but we also don’t want to break existing code which is out there and works correctly.

    Therefore, the Code Analyzer tries to provide an indication of the current behavior and direct users away from it. For this specific code example, it provides these two messages on the “or” in the MATLAB Editor:

    This statement (and possibly following ones) cannot be reached.
    Consider using newline, semicolon, or comma before this statement for readability.

  9. Marshall says:

    It looks like this is just syntax muddling. Rewritten with better formatting, we get this:

    function test
        try
            if(false)
                or(true);
                disp('Yaba');
            else
                disp('Daba');
            end
        catch
            disp('Doo!');
        end
    end

    We never actually reach the line “or(true)”, which would throw an error, causing the catch block to print ‘Doo!’, so instead we simply print ‘Daba’. The parentheses are required in order to have the (false) alone apply to the if statement, as opposed to what comes after.

    Regarding the other questions:

    if (false) or (true) % variant #1
    if (true) or (false) % variant #2 — my guess is this will print ‘Doo!’, since the or(false) will throw an error
    if (true) or (10< 9.9) % variant #3 — will also print ‘Doo!’ for the same reason: “or(10<9.9)” is invalid
    if true or 10< 9.9 % variant #4 — will also print ‘Doo!’, but this time it’s because “true or 10< 9.9” or: “10>9.9 or 10<9.9” is invalid — the or function requires 2 arguments

    • Marshall says:

      Ha, it looks like variant #4 got me. Quite clever. When pasted in Matlab it’s a bit more obvious because the “10< 9.9" is coded purple, indicating character arrays.

    • Marshall says:

      (I meant variant #5)

  10. Brad Stiritz says:

    Hi Yair, I would expect the conditional expression to fail during parsing, and therefore lead to “Doo!” output per catch block. The proper “functional” syntax for logical OR is as follows:

    >> or(false,true)
    ans =
      logical
       1

Leave a Reply

Your email address will not be published. Required fields are marked *