bugGNU Octave - Bugs: bug #56187, Support local functions at end of...

 
 

bug #56187: Support local functions at end of scripts like Matlab

Submitter:  Andrew Janke <apjanke>
Submitted:  Sun 21 Apr 2019 01:10:57 PM UTC
   
 
Category:  Interpreter Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Feature Request
Status:  None Assigned to:  None
Originator Name:  Open/Closed:  * Open
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Tue 31 May 2022 05:28:16 AM UTC, comment #18: 

I'm changing the item group for this report to be "Feature Request" instead of "Matlab Compatibility".  There are compatibility concerns, but supporting functions with local scope in script files is a new feature.

John W. Eaton <jwe>
Group administrator
Mon 30 May 2022 02:00:32 PM UTC, comment #17: 

This incompatibility has been popping up on the help lists from time to time. Is this possibly something that could be decided upon in time for the octave 8 release?

Nicholas Jankowski <nrjank>
Group Member
Fri 27 Nov 2020 01:48:55 PM UTC, comment #16: 

I just hit this (compatibility) issue as well. Are there any news or plans to implement this change?

(I only ask this, because to me there seemed to be a consensus in the discussion of this thread already: to add a special tag for a script file that is intended to contain global functions).

Hartmut <hardy>
Tue 23 Apr 2019 07:01:31 PM UTC, comment #15: 


> I think something backwards compatible would be nice, how about a special comment tag that marks the m-file as an import script?


Oh, that would probably be better. And would be a back-compatible way of addressing your next comment.

Matlab uses `%#...` comments as compiler pragmas, for stuff like `%#function` and M-lint inspection controls. Maybe a `%#globalfunctions` pragma?

Andrew Janke <apjanke>
Tue 23 Apr 2019 06:33:03 PM UTC, comment #14: 

RE: comment #13:  Ah, right, like an include file that includes a set of variables and function definitions.  OK.

I think the real problem with globally visible functions in a script file is that reloading the script if it changes in order to get updated function definitions is problematic.  The script could do more than just define functions.  Executing the script again at a random time is probably not good.  And I think we currently do that (don't try to reload function definitions if they come from a script file).  So maybe all that is needed is some other way to indicate "this is a script file that may contain functions that should be globally visible" instead of the old "1;" thing.

John W. Eaton <jwe>
Group administrator
Tue 23 Apr 2019 06:04:53 PM UTC, comment #13: 

It is possible that an Octave user has a script file that looks like a Matlab script with local functions


a = 1;
b = 2;
## more delarations

## some code that does things

function myfunc1 ...

function myfunc2 ...
...
endfunction


In this case, the Octave expected behavior would be to execute the declarations and script code, and to define the functions globally so they can be called by the user later.

Providing a comment tag that the user can add to their file to mark this as an import script, even though the format looks exactly like a Matlab script with local functions, would be a good thing.

Mike Miller <mtmiller>
Group Member
Tue 23 Apr 2019 05:55:13 PM UTC, comment #12: 


>  Maybe we could repurpose the `global` keyword


I think something backwards compatible would be nice, how about a special comment tag that marks the m-file as an import script?

The following would work in old versions of Octave and in the latest Octave if this support is added


## OCTAVE-SPECIAL-IMPORT-MARKER
1;

function myfunc1
...


Mike Miller <mtmiller>
Group Member
Tue 23 Apr 2019 01:10:07 PM UTC, comment #11: 


> Many uses of script files that contain functions could be handled perfectly well with Matlab-style local functions that are not globally visible. Converting Octave scripts to work that way would be fairly easy.


I agree. I think that would be better programming practice, too: keeping the scope of definitions only as wide as necessary, and reducing the risk of collisions in the global namespace.

> If people really want to be able to define globally visible functions in a script file, then maybe we could provide some way to mark them as such (an export function or command?).


Maybe we could repurpose the `global` keyword, and use it as a qualifier for those functions?


global function foo(x)
  [...]
endfunction


Or maybe a global functions block to stick them in, like classdefs have static method blocks?


global functions
  function foo(x)
    [...]
  endfunction
  function bar(x)
    [...]
  endfunction
endfunctions


Andrew Janke <apjanke>
Tue 23 Apr 2019 01:02:02 PM UTC, comment #10: 

I suppose it is possible, but I don't see why they would be considered nested unless they were actually defined inside another function (not just the script).

If we discourage the expectation that a script will define globally visible functions, then any future transition will be easier.

Many uses of script files that contain functions could be handled perfectly well with Matlab-style local functions that are not globally visible.  Converting Octave scripts to work that way would be fairly easy.

If people really want to be able to define globally visible functions in a script file, then maybe we could provide some way to mark them as such (an export function or command?).

John W. Eaton <jwe>
Group administrator
Tue 23 Apr 2019 11:35:24 AM UTC, comment #9: 

I see a possible conflict in the future, but this is purely speculative on my part: Because Matlab supports nested functions and local functions, but does not support command-line functions (and their paradigm really isn't to do that), I would bet that if Matlab were to add support for functions in the middle of script files in the future, they would be treated as nested functions local to the script, instead of global command-line functions. At which point Octave's support for command-line functions in scripts would be incompatible with it.

This is purely hypothetical, though.

Andrew Janke <apjanke>
Tue 23 Apr 2019 11:31:34 AM UTC, comment #8: 

Since Matlab requires local function definitions to all be at the end of the script, and Octave requires all functions defined in scripts to be available before they are used, I don't see a conflict except for Octave scripts that are used as include files to define multiple global functions.  Although I thought that was a nifty feature back in the day, I would be OK with discouraging it now.

John W. Eaton <jwe>
Group administrator
Tue 23 Apr 2019 11:23:34 AM UTC, comment #7: 


> I'd be curious to know what Matlab does with a script file that contains more code after local function definitions. Is it a parse error, silently ignored, something else?


Parse error.

Andrew Janke <apjanke>
Mon 22 Apr 2019 08:16:15 PM UTC, comment #6: 

On the maintainers list I asked for someone to run a couple of scripts to test.

I don't see that detecting Matlab-style local functions based on what the file contains is much different from detecting subfunctions vs. nested functions based on the presence of "end" tokens.

I also don't see that we have much of a choice about whether to support Matlab-style local functions in scripts.

John W. Eaton <jwe>
Group administrator
Mon 22 Apr 2019 06:46:02 PM UTC, comment #5: 

Yeah, I'm not sure that trying to detect the format of the file and update the parsing rules based on that is a good thing to do at all.

I'd be curious to know what Matlab does with a script file that contains more code after local function definitions. Is it a parse error, silently ignored, something else?

Mike Miller <mtmiller>
Group Member
Mon 22 Apr 2019 05:08:12 AM UTC, comment #4: 

I think we can detect the Matlab-style local functions by noting that all the functions definitions occur at the end of the script and that once a function definition is parsed, the only thing that we see in the file are more function definitions and no other code.  Otherwise, we could proceed as we do now and make functions in the script globally visible.  That still leaves a change in behavior for scripts that begin with some trivial code like "1;" and then simply define functions.  We could recognize that as a special case (it's been the recommended way to do this forever) though I'm not sure that's a good thing to do.

John W. Eaton <jwe>
Group administrator
Sun 21 Apr 2019 04:30:09 PM UTC, comment #3: 

It's not a dealbreaker for me personally. But I think there are a lot of Octave users who value being able to define a set of global functions in a single include file.

If we could support this feature as well as provide a way to continue to include or source functions from a file into the global namespace, I think that would make everyone happy. If the 'source' function did something special, for example, or if we add a new function like 'include', to carry on the ability to define multiple global functions in a single m-file.

Mike Miller <mtmiller>
Group Member
Sun 21 Apr 2019 04:10:14 PM UTC, comment #2: 

Ah, you're right. I didn't realize they stayed available after the script run. But some simple testing confirms that.

Hmm. I don't see a way to add local function support in a way that doesn't break command-line function support. Maybe this is a WONTFIX.

Andrew Janke <apjanke>
Sun 21 Apr 2019 04:03:29 PM UTC, comment #1: 

Correct me if I'm wrong, but adding support for script local functions will also break the long-standing current behavior, where a script can be used like an include file. Currently functions defined in a script become available at the command line, since they are parsed as command line functions. If we change this to be true script local functions, they will only be visible to that script, right?

Mike Miller <mtmiller>
Group Member
Sun 21 Apr 2019 01:10:57 PM UTC, original submission:  

Both Matlab and Octave now support the use of local functions inside scripts. But they do it differently: Octave requires that the local functions be defined before their use, whereas Matlab requires that all local functions be defined at the end of the script. So any script that uses local functions will only work on one of the two, depending on how it's written.

It would be nice to add support for defining local functions at the end of scripts, for Matlab compatibility, and more flexibility in how users write their source code.

References:
- https://stackoverflow.com/questions/50404236/error-when-running-simple-script-containing-local-function-in-octave
- https://stackoverflow.com/questions/55770635/how-to-write-a-single-octave-script-with-function-definitions-compatible-with-ma

Andrew Janke <apjanke>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Digest:
   bug dependencies.

 

Carbon-Copy List
  • -email is unavailable- added by nrjank (Posted a comment)
  • -email is unavailable- added by hardy (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by apjanke (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 2 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2022-05-31 jwe Item GroupMatlab Compatibility Feature Request
    2022-05-30 mmuetzel Dependencies- bugs #62543 is dependent

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code