florianschanda / miss_hit

MATLAB Independent, Small & Safe, High Integrity Tools - code formatter and more
GNU General Public License v3.0
160 stars 21 forks source link

Support octave in-script function definitions #198

Closed EmilyGraceSeville7cf closed 3 years ago

EmilyGraceSeville7cf commented 3 years ago

Hello! My teacher written the following code:

clear all

function z = f(x, a)
    n = size(a)
    sum = 0;

    for i = 1:1:n(1)
        sum = sum + a(i) * x^(i - 1);
    end

    z = sum;
end

n = 4;
x = [1 3 5 7]';
y = [2 2 4 4]';

for i = 1:n
    for j = 1:n
        X(i, j) = x(i)^(j - 1);
    end
end

a = X^(-1) * y;
disp(a)

f(2, a)
f(4, a)
f(6, a)

I want to understand why when I run mh_lint test.m I get:

In test.m, line 14
| n = 4;
| ^ error: expected end of file, found IDENTIFIER instead
MISS_HIT Lint Summary: 1 file(s) analysed, 1 error(s)
apjanke commented 3 years ago

Hi @alvinseville7cf!

Your code is a script which has a function definition in the middle of it. That is valid Octave code, but not valid Matlab code. In Matlab, scripts which have local functions must put the function definitions down at the very end of the script, after any statements which are outside function definitions. That's probably what's going on here.

florianschanda commented 3 years ago

Thank you @apjanke for answering!

I will keep this ticket open as a feature request for supporting in-script functions if the octave mode is on. I had no idea this was possible.

apjanke commented 3 years ago

I had no idea this was possible.

Yep, it's a thing. The weird thing is that the semantics of it are significantly different from the Matlab version of local functions inside scripts: in Octave, if there's a function statement inside a script, it's called a "command line function", and it actually defines a global function at run time (just like it existed in a separate .m file), not a local function that is scope-limited to the containing script!

florianschanda commented 3 years ago

Thats... good to know and clears up a lot! I did read https://octave.org/doc/v6.2.0/Script-Files.html#Script-Files and I was sufficiently confused because the Octave devs also seem to not like talking about semantics too much. :/

Btw, since you seem to know about Octave, and I do want to support it, feel free to add missing bits to #43, or add a whishlist of priorities.

apjanke commented 3 years ago

the Octave devs also seem to not like talking about semantics too much. :/

You ain't wrong. Octave is one of those languages like Perl, where the interpreter implementation kind of is the language spec.

Btw, since you seem to know about Octave, and I do want to support it, feel free to add missing bits to #43, or add a whishlist of priorities.

Thanks! Maybe in April? I'm under big day-job deadlines until the end of March.

florianschanda commented 3 years ago

Hi @alvinseville7cf your original code now produces this message:

In potato.m, line 3
| function z = f(x, a)
|              ^ error: script-global functions are an Octave-specific feature; move your functions to the end of the script file or use the --octave mode
MISS_HIT Lint Summary: 1 file(s) analysed, 1 error(s)

This should be way more clear than before. If you do use mh_lint --octave yourfile.m then you now get:

MISS_HIT Lint Summary: 1 file(s) analysed, everything seems fine