Rexx ‘return’ statement is not able to return a string
Attempts to make it return a string fail; I can do ‘return ?’ , it parses ok, but I don’t know what that means.
This works
/* rexx */
options levelb
say "result =" blah(1)
return 0
blah: procedure = .string
arg a = int
return "Rene"
However this does not - it seems the parser can't handle a function with no arguments ... which is an issue for sure!
/* rexx */
options levelb
say "result =" blah()
return 0
blah: procedure = .string
return "Rene"
maybe factor in https://github.com/adesutherland/CREXX/discussions/264 because using an exposed variable from main() also needs to be possible without an ARG
I think this should be fixed in develop now
/* test empty say */
options levelb
say "now follows an empty say:"
say
say "this was an empty say:"
return 'string'
still gives:
Error @ 6:8 - #31.1, "\'string\'"
1 error(s) in source file
while return 0 works without problem.
in addition to the previous: it seems that return 0 (or another number) is still mandatory; sources won't compile without it. Code that runs off the end should implicitly return 0 or ""; this is awkward with running script-like things compatibly in netrexx, because in netrexx(Java), a main(args=String[]) cannot return anything, so for my compatible mini-scripts this would be good.
The issue is that
/* test empty say */
options levelb
say "now follows an empty say:"
say
say "this was an empty say:"
return 'string'
is "syntax candy" (by which I mean "is converted to for the convenience of developers") for
/* test empty say */
options levelb
main: procedure = .int
say "now follows an empty say:"
say
say "this was an empty say:"
return 'string'
So you could always use
/* test empty say */
options levelb
main: procedure = .string
say "now follows an empty say:"
say
say "this was an empty say:"
return 'string'
or better for you
/* test empty say */
options levelb
main: procedure
say "now follows an empty say:"
say
say "this was an empty say:"
So that's the problem. We have some options
- Do nothing - you just have to add the "main: procedure"
- Make the syntax candy assume no return value. i.e. add "main: procedure" without the ".int". I chose ".int" because that is what main() from the OS expects but for the syntax candy perhaps no return code is more natural?
- Remove the syntax candy - as it's confusing!?
- Make the syntax candy smarter - if there is no return statement use "main: procedure", no return value (0 implied), otherwise use "main: procedure = .int". Note that main() must return an .int, in general OS's don't support a string return from main()
What do you think?
PS It should be noted that arguments into main are STILL not implemented!
my vote is for (2) in the short term and (4) in the long run Java cannot return from main - my primary use case (I admit that frankly) is NetRexx compatible scripts so I can go native if needed.
I had forgotten that java main was type void!
ok
/* test empty say */
options levelb
say "now follows an empty say:"
say
say "this was an empty say:"
return '123'
returns 123
/* test empty say */
options levelb
say "now follows an empty say:"
say
say "this was an empty say:"
return 0
And
/* test empty say */
options levelb
say "now follows an empty say:"
say
say "this was an empty say:"
return 'string'
Causes a conversion error - which seems reasonable.
So I am marking as resolved :-)
'normally' - on Classic Rexx - what is returned with a return statement goes into the RESULT variable (when called from an exec) and what is returned to the OS comes from EXIT n, to TSO or as a batch step return code and I think in our case, to the calling shell process. But if we cannot compile, we cannot return. Because what is 'returned' in Rexx is mostly strings, we should maybe change the default of the generated syntax candy to .string and leave the conversion error for if we try to EXIT with a string?
I think that is what we do
options levelb
say "hi"
return '100'
returns 100 to the os
@rvjansen given that we DO return a rc if the return value can be converted to an integer (or raise a signal if not) - can we also close this issue?
I still think EXIT should be in charge of returning returncodes and ‘return’ should be able to return a string in RESULT when called by another module - even when it is generated by syntactic sugar. A string containing a number then still could be deposited in RESULT when needed.
But if that is awkward we could document the difference and leave it like this.
Oh - I can set the RESULT environment variable. I just was not understanding the requirement!
In classic rexx it is possible to have a program file hang around in a directory or concatenation and call that from another program or use it by itself - with the complication that it cannot start with a PROCEDURE statement in that case, but is treated as a procedure anyway. In level b we must have an exposed function to call and it would be odd to use an exported main() for that (if that is at all possible). So I am closing this one, but still wondering what is needed for level C which is supposed to be compatible with classic. In this case the generated main should be an exposed version of the filename and probably returning a string. But that is for later.