-
Notifications
You must be signed in to change notification settings - Fork 15
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
Make it possible to switch on optional parameters/parameter defaults/rest parameters #112
Comments
How would these work together? Well, with three different pragmas, there are
Note that we're not talking about combining the pragmas themselves (which is fine, all three at the same time), but using two syntactical extensions together on the same parameter. |
An interesting bit of parsing manifests itself when we start thinking about a script with the preamble
versus
...both of which should obviously work and produce "the same" parser in the current compunit. To be precise, one might naively think that both these pragmas extend
but dissallowed
In other words, there's more to it than just adding stuff to the end of a rule, and possibly to the beginning. This is problematic for conventional Perl 6 grammars, because grammar rules are methods, which are routines, which are opaque and don't allow modification "in the middle". The standard route for extensibility in Perl 6 grammars is subclassing, along with protoregexes. But protoregexes require forethought — the base grammar author had to be aware that a certain point was a desirable point of extension for pragma/slang/DSL authors. What 007 (and ultimately Perl 6) needs is something more like CSS
AOP and pointcuts also come to mind. Two different modules attaching a rule to the exact same point — also interesting to consider. To take a concrete example, consider a In other cases they might choose to impose an internal order even when they go on the exact same point. (Perhaps via some kind of voting process.) In yet other cases (and the case of These are just a few comments about the parsing. There are also considerations regarding extending the action methods (which basically need a way to "decorate" Q nodes) and runtime behavior, in this case the signature binder. |
As OP stated, a non-passed optional parameter binds to
But this is going to rub up against #33, in a way I hadn't thought of before:
Here are possible solutions.
|
Last one for me. |
Aye, that one does make some sense, and I like it for its intuitiveness. I don't have the certainty to declare that it's a completely consistent, trap-free solution, though. |
Also interesting to go check what TypeScript does in this space, after nullable types landed. |
All parsing challenges aside, the trouble with making signature parsing truly extensible is that it also has consequences for the signature binder, a part of the runtime. Two options present themselves:
You're probably thinking what I'm thinking — the second option sounds like a lot more fun. Even doing it just for kicks to see how such a binder API would look in the language might be worth it. But there are still lingering doubts and problems. For one, extending the signature binder will have to be a global effect (as opposed to locally modifying a parser for a particular scope). The difference is that runtime values are not constrained to scopes or even compilation units. Higher-order functions can arrange to have an "enhanced" function be called in a region of code that was never aware of such enhancements in the first place. This troubles me. Or maybe a routine's signature binder should actually hang off the routine itself? Each routine carries around (a reference to) the signature binder, which has been assigned by the parser so it has all the information needed. Very, uh, object-oriented — the receiver knows how to receive the message. But this possibility also fills me with dread and vertigo. |
Oh, that sounds really fun! Next up is implementing |
It bears stressing that parameter defaults do change the way we do signature binding... or at the very least brings out a feature of it that wasn't necessary before. Here's the example I used in OP:
Note that |
Oh, and I would expect
to be a compile-time error, because initializing a variable with itself is always a thinko. |
[snark]Python developers want to have a word with you :P[/snark] |
I got that joke. 😄 I taught a beginner's Python course two weeks ago where I explained this language design mistake (because what else can you call it?) as it incarnates both in function parameter defaults and in class property defaults. Funnily enough, Python is quite principled when it comes to local variables, and won't take any prisoners:
"Referenced before assignment" is a good description of the thinko, actually. Unfortunately, it throws away the same principle when it comes time to talk about parameter defaults...
...or class property defaults...
Needless to say, we will take a leaf from Perl 6's book here, not Python's. (Perl 6 is happy-go-lucky about many things, but working on 007 has made me realize that scoping is not one of those things.) |
Also, while it's always hilarious to tease Python about scoping snafus, it would be hypocritical to let Perl 5 completely off the hook:
You're reading that right — we can still access the outer Perl 6 is wise to such tricks, and politely informs you that you have unreasonable expectations:
|
An exercise in Qtree extensibility.
Something like this:
The addition could happen in two steps:
The second step is far tougher, and will likely require exposing some of the function calling mechanism as a public interface or a MOP. But it's also bound to shake out interesting answers to how to safely evolve 007 from userland.
Note that all three of these pragmas ought to be able to work independently, with or without any of the other two.
The text was updated successfully, but these errors were encountered: