Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request - multiple returns from a function #138

Closed
tom-leys opened this issue Sep 4, 2024 · 4 comments
Closed

Feature request - multiple returns from a function #138

tom-leys opened this issue Sep 4, 2024 · 4 comments

Comments

@tom-leys
Copy link

tom-leys commented Sep 4, 2024

Allow functions to "pack tuples" of return values and unpack them on assignment. If the number of return values does not match the calling line then that is an error.

This lets you do some processing and return multiple useful things per item you processed.

def function(a, b)
  return a * b, a + b
end

mul, add = function(2,4)

Naturally one workaround for non-reentrant functions is to return additional values in globals.

@cardillan
Copy link
Owner

I have some plan for returning additional values from functions. My intent is to do so through function parameters declared as output, i.e.

def function(a, b, out c)
    c = a + b
    return a * b
end

mul = function(a, b, add)

This approach seems easier to implement in the parser/grammar. I need to rewrite the grammar anyway and I hope I'll be able to get to it soon.

@tom-leys
Copy link
Author

tom-leys commented Sep 5, 2024

Cool!

I think like C# it should be a compile error for the caller to not explicitly mark a variable as out

// Correct
mul = function(a, b, out add)

// error
mul = function(a, b, add)

// error
mul = function(a, b, out 10 + 20) (must use a named variable for out)

In C# there are two types of out. There is out and ref. out defines a variable in the function for the caller to use. ref requires the caller to have already created a variable, so the function receives an initialized variable to modify.

If you want to do just one, ref is probably the more useful one.

The example function from above should use out, however in my reactor example ref would have been useful. Instead I had to do this

fuel_1 = start_reactor(reactor1, 1, emerg_shutdown, fuel_1, t_startup1)
t_startup1 = RET_T_STARTUP
update_fuel(fuel_1, ULD_IN_1, ULD_OUT_1)

fuel_2 = start_reactor(reactor2, 2, emerg_shutdown, fuel_2, t_startup2)
t_startup2 = RET_T_STARTUP
update_fuel(fuel_2, ULD_IN_2, ULD_OUT_2)

Note that here I am wanting to use t_startup1 / 2 as a ref, but doing it via a global. It would have also been better to pass fuel_1 as ref also.

start_reactor(reactor1, 1, emerg_shutdown, ref fuel_1, ref t_startup1)

@cardillan
Copy link
Owner

I do envision both out and ref parameters. I wanted to support in and out keywords when declaring the parameters, and the reference-like parameters would be declared in out, e.g. def function(in a, out b, in out c). in would be the default when omitted.

I don't want to invent new syntax at all costs, but there are no references in mlog. Marking the parameter as ref might suggest it is a true reference and that changes to, say, a global variable passed as a ref would be immediately visible, which isn't true.

On the other hand, in keyword is already used in other contexts, so if there was a way to express the ref parameters in some other way, I'd be glad.

Explicitly marking the variable in the function call is also a good idea.

@cardillan
Copy link
Owner

This is now covered by #142.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants