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

Implement named arguments, Python-style #299

Open
masak opened this issue Jun 1, 2018 · 4 comments
Open

Implement named arguments, Python-style #299

masak opened this issue Jun 1, 2018 · 4 comments

Comments

@masak
Copy link
Owner

masak commented Jun 1, 2018

That is, if you have a function

sub foo(x, y, z) {
    say(`The ${x} to the ${y} to the ${z}`);
}

You could call it as (for example)

foo("x", y="y", z="z");

Python imposes the restriction that a positional argument never come after a named one. I suggest we do the same.

I'm slightly open to the objection that = is not the right syntax there, as it's not Perl-y enough. Perl 6 uses = for parameter defaults, but uses y => "y" or :y("y") for named arguments. I suspect if you'd ask TimToady he'd say that it's "because it's not an assignment". Maybe in 007 y: "y" (like in object properties) would be the closest analogue. But I remain on the fence. (Update: Decided on colon; see below.)

Shout-out to #112 and to the fact that I still haven't really started thinking about how a pluggable signature binder would need to work. 🎩 (Edit: Have now, in #329.)

@masak
Copy link
Owner Author

masak commented Jul 13, 2018

I hadn't realized it before, but you can send keyword arguments to dict in Python, meaning that you can construct dicts using the constructor instead of using the dedicated {} syntax.

The {} syntax still has merit, of course. I don't think we should remove it. But the fact that you can initialize dictionaries that way is in some sense a weak argument against overloading block and dictionary syntax. (On the gripping hand, it's hard to imagine something like dict comprehensions without the dedicated syntax.)

If we decide to allow Dict instances to be created nonempty via the constructor, it would be nice to have a story for how we declare named slurpy parameters.

@masak
Copy link
Owner Author

masak commented Jul 23, 2018

I'm slightly open to the objection that = is not the right syntax there, as it's not Perl-y enough. Perl 6 uses = for parameter defaults, but uses y => "y" or :y("y") for named arguments. I suspect if you'd ask TimToady he'd say that it's "because it's not an assignment". Maybe in 007 y: "y" (like in object properties) would be the closest analogue. But I remain on the fence.

I'm no longer on the fence; we should do it with the colon.

Why? Becuase = already means something in that position: assignment. The way 007 looks today, it'd be confusing to introduce a new conflicting syntax there. Colon, on the other hand, is free (and strangely consistent with the dictionary key/value separator).

It's possible for #279 to come down in such a way that the direct ambiguity goes away, but (a) that is not at all certain, and (b) even if it did, there would still be some sort of mental ambiguity left.

@masak
Copy link
Owner Author

masak commented Nov 20, 2018

(And #279 came down in such a way that it'd be confusing to use = for that.)

@masak
Copy link
Owner Author

masak commented Nov 20, 2018

I already started implementing this in a branch, but I hit an interesting snag, which I'll quickly describe:

Macro calls are calls. As such, they have argument lists. It's in the argument lists we are adding the new named argument syntax. In other words, macro invocations get named arguments too. Fine.

But one big way in which function invocation and macro invocation differ, is that the former takes evaluated arguments (that is, their Qtrees have been interpreted by the runtime), but the latter just wants the dry Qtrees as-is.

The solution is probably (and I don't know if I realized this back then) to separate the "evaluate arguments" logic out to Q.Postfix.Call, where it gets to eval for functions, but not for macros since they will have already been intercepted by the compiler.

Need to try this. A bunch of language changes around constructors are blocking on this feature.

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

No branches or pull requests

1 participant