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

Call-by-name functions #45

Open
SnirkImmington opened this issue May 25, 2018 · 1 comment
Open

Call-by-name functions #45

SnirkImmington opened this issue May 25, 2018 · 1 comment
Labels
area: AST Issues which affect AST code area: syntax Syntactical changes to the language change: expansion A change which includes new features, improvements, or APIs

Comments

@SnirkImmington
Copy link
Collaborator

SnirkImmington commented May 25, 2018

I'm writing a regression in the typeck branch, to go back to call-by-argument functions. The current master (as of 8a20dc5) requires that all parameters to functions be named, and allows variables to be used as the names:

fn foo(x, y)
    if x == 0 => 1 else foo(x: x -1, y)

The exception for this is single argument functions - for them, the naming rules are ignored.

Call by argument name

Okay, here's how it should work:

When you're writing a function, you can ask for named parameters after a certain index with the keyword named:

// exp(5, pow: 2)
fn exp(base: int, named pow: int) -> int

// stats(median: x, mode: mode)
fn stats(named median: int, mode: int) -> int

The compiler should also emit a warning if you have two or more arguments of the same type which are not named.

What about when you're calling a function? We enforce call by parameter name. All parameters after named must be call-by-name in callers.
This is done by the syntax paramName: <expr>.

If we allow callers to specify names whenever they want, however, the caller cannot rename parameters without breaking API compatibility. This may be a worthwhile tradeoff, however.

Motivations

As with other languages with call-by-name functions (especially statically typed ones, like C#), our motivation is to make code more readable.

I can imagine guidelines for named arguments reading as:

Use named parameters for parameters of a function that

  • are of the same or similar type, cannot be reordered, and for which a standard order is not obvious
  • values not identifiable by name (such as flags which use a boolean instead of named enum)
@SnirkImmington SnirkImmington added area: AST Issues which affect AST code area: syntax Syntactical changes to the language change: expansion A change which includes new features, improvements, or APIs status: blocked Cannot be done until other changes are made labels May 25, 2018
@SnirkImmington SnirkImmington changed the title Call-by-argument-name functions Call-by-name functions May 29, 2018
@SnirkImmington SnirkImmington removed the status: blocked Cannot be done until other changes are made label May 29, 2018
@Timidger
Copy link

I think you should reverse it. By default fields are explicitly named at the call site and to opt out of that you use a keyword in the function definition (e.g implicit).

Except for simple functions (which will be few per module and mostly concentrated on the std and very generic libraries (e.g. standard collections, math, random, etc.) you almost always want explicit names at call sites.

I would argue you don't want to have the special case one argument rule because it's simple enough to add the implicit keyword.

And on the other side you don't want to have an explicit keyword because it will get annoying to type out and convince the user to not write it because the user is a programmer and a programmer is lazy.

Finally, it's better for APIs. Explicit to implicit is not a breaking change (because you can still specify the name). Implicit to explicit IS a breaking change. So removing the keyword now makes it a breaking change instead of adding it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: AST Issues which affect AST code area: syntax Syntactical changes to the language change: expansion A change which includes new features, improvements, or APIs
Projects
None yet
Development

No branches or pull requests

2 participants