Jira (PUP-9695) Add ability to return multiple named values from a function.

16 views
Skip to first unread message

Thomas Hallgren (JIRA)

unread,
May 8, 2019, 8:44:03 AM5/8/19
to puppe...@googlegroups.com
Thomas Hallgren created an issue
 
Puppet / New Feature PUP-9695
Add ability to return multiple named values from a function.
Issue Type: New Feature New Feature
Assignee: Unassigned
Components: Language
Created: 2019/05/08 5:43 AM
Priority: Normal Normal
Reporter: Thomas Hallgren

This is inspired from Golang where it is possible to return several values from a function and also to declare variables as part of the declaration of the return value.

Consider the following function:

function multiReturn() >> Struct[a=>String,b=>Integer] {
  $a = 'hello'
  $b = 3
  return { a => $a, b => $b }
}

this could instead be written as:

function multiReturn() >> (String $a, Integer $b) {
  $a = 'hello'
  $b = 3
}

The result would in both cases be:

{ a => 'hello', b => 3 }

This new syntax also aligns well with the already existing ability to assing multiple returns to named variables of an Array, e.g.

[ $a, $b ] = multiReturn()

Add Comment Add Comment
 
This message was sent by Atlassian JIRA (v7.7.1#77002-sha1:e75ca93)
Atlassian logo

Henrik Lindberg (JIRA)

unread,
May 8, 2019, 9:24:03 AM5/8/19
to puppe...@googlegroups.com
Henrik Lindberg commented on New Feature PUP-9695
 
Re: Add ability to return multiple named values from a function.

I would restrict this so that the "assignment sets one returned value" only is available when the return is specified using the new syntax.
Further, when return is specified this way, variables must be assigned, and that if they are not, the return specification must allow an undef value. An error would be raised otherwise.

A corner case is if logic assigns to "return variables" but then explicitly return a hash (calling return()).
Can you call return() at all - what does that mean?

Henrik Lindberg (JIRA)

unread,
May 8, 2019, 10:02:02 AM5/8/19
to puppe...@googlegroups.com

Further details:

  • it should be allowed to specify that an input parameter is also returned - and when done this way, the type of the returned does not have to be specified since it is defined by the parameter. (naturally, It would be allowed to narrow it).

    foo(String $a) >> ($a) { }
    

  • An assignment must be made in the function's scope - cannot do this in a nested inner scope, and the assignment requirement cannot be fulfilled by a variable set in an outer scope.

Henrik Lindberg (JIRA)

unread,
May 8, 2019, 10:03:03 AM5/8/19
to puppe...@googlegroups.com

Question, should it allow default values to be used if the variable is not assigned?

Thomas Hallgren (JIRA)

unread,
May 8, 2019, 12:51:04 PM5/8/19
to puppe...@googlegroups.com

Not sure if it makes sense to be able to narrow the returned type when passing a parameter, given that the passed variable is immutable.

I think allowing defaults would be a good thing. Without it, defaults must be explicitly stated within the function itself and perhaps in multiple places. That can be a tedious task since the parameter is immutable.

It should be allowed to call return(), but only without arguments. We could allow returning a hash but I don't really see the point in that and it introduces new questions. What if the hash contains more variables? Is that allowed? If it contains fewer variables? Will the declared variable be used in that case? Etc.

Henrik Lindberg (JIRA)

unread,
May 8, 2019, 2:06:03 PM5/8/19
to puppe...@googlegroups.com

Basically that means that you must return the specified variables (you can set them to undef (or not set them and get undef if that is allowed). You can for example not specify that the function can return an undef instead of a Hash. (I am fine with that). Then, a return() is the same as return(undef), and the return must be caught to transform the returned value to what is specified. A return of NotUndef would be an error.

Henrik Lindberg (JIRA)

unread,
May 8, 2019, 2:07:03 PM5/8/19
to puppe...@googlegroups.com

On narrowing - not important, but the function may guarantee that a returned value is narrower than the input - it could do its own type assertions for example.

Thomas Hallgren (JIRA)

unread,
May 8, 2019, 4:36:04 PM5/8/19
to puppe...@googlegroups.com

I don't think that a function that declares multiple return values like this should ever be able to return an undef. It will always return a hash containing the values of the variables. This is analog with a function that declares that the returned type is a Struct. It's not allowed to return undef. Just calling return() without arguments should mean "return here using whatever value that the variables have at this point". The sole purpose of doing that is to break out of the function at some other place than at the end.

Henrik Lindberg (JIRA)

unread,
May 8, 2019, 6:08:02 PM5/8/19
to puppe...@googlegroups.com

Ok - those constraints are good. I was pointing out that return() is a call, and a return without value is a "return(undef)". A function that has the "output variables" declared would need to catch the return and change it to a return of the struct (and error if user called return with something other than undef. At the moment there is no difference between return(undef) and just undef().

Jorie Tappa (JIRA)

unread,
May 13, 2019, 1:02:04 PM5/13/19
to puppe...@googlegroups.com

Jorie Tappa (JIRA)

unread,
May 13, 2019, 1:02:05 PM5/13/19
to puppe...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages