-
Notifications
You must be signed in to change notification settings - Fork 23
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
Improve overloaded resolution for template with untyped parameter #402
Comments
Your proposal make sense but I think |
I'm not sure I understand what the alternative to |
You would use |
i disagree but this should be discussed in its own dedicated RFC instead of scattering discussion on this in many places; 1 RFC = 1 topic (linking to an RFC is what should be used instead) |
I don't think nim-lang/Nim#18618 is the right fix; it doesn't help with this important case: optional params with a block trailing param, a very common pitfall that requires annoying workarounds (see nim-lang/Nim#14346); in fact even the example motivating this RFC could be best re-written with a single overload (instead of 2) and optional params: when true:
template fn(a = 1, b = 2, body) = discard
fn(1, 2):
foo1
foo2
fn(1): # bug: doesn't work
foo1
foo2 IMO this is what should be fixed first, it would not only solve the problem described in PR description (even with the 2 overloads), but it will also work with optional params as shown here. notefor non-block param, the following works, using named param: template fn(a: int, body) = discard
template fn(body) = discard
fn(body = foo1) possible implementationin sigmatch, if the last param uses block syntax, constrain its position to be the last formal parameter linksnim-lang/Nim#17429 |
@timotheecour Yes, I thought about it, with the case that have optional parameter(with default value) combine the last untyped param. Fix this need to change the parameter and argument bind algorithm: bind the first N arguments with first non-optional parameter, bind the last M arguments with last non-option parameter, then the middle arguments treated as optional paramter. But I think it need to be handled with another RFC. |
@timotheecour I think the PR nim-lang/Nim#18618 will fix lots of untyped parameter's undefined symbol compiler error with overloaded template, of case not all. You can still improve this, but that's not the contradict with this PR. |
@timotheecour I have an idea.
|
I like it! can you open a separate PR for this? (you can leave the other PR open in the meantime); I expect this will make the other PR obsolete in the end as it's a more general fix. The 2 phase approach is good (reject 1st based on param-argument index mismatch taking into account everything except the types of arguments, then if 1st succeeds, reject based on type mismatch, with special case for untyped params as optional further refinement)
I think this is a refinement that can be done in a separate PR; we'll already get lots of benefits from the 2 step sigmatch. Checking for undefined symbols may not be robust, at least needs more thought. |
Making default arguments work with untyped bodies sounds like it should be part of a completely seperate RFC. Possibly combined with named only arguments support as a pragma or a new postfix operator so it doesn't break existing code. |
here you go: #405
i don't see a need for that, it shouldn't break code (please provide an example otherwise) /cc @slangmgh looks like the idea you described in #402 (comment) should be able to address #405; a PR for that would be most welcome, it's a very common use case; I'd be happy to review and test |
Working implementation of the described solution in the RFC as reference for future/just in case nim-lang/Nim#21673 |
Ok well if we aren't implementing this we should at least document this limitation along with the workaround as outlined here. |
Can someone explain why this happens? Is |
To resolve overloads, each argument in a call expression is iterated over, and if the argument type for an overload at some position is not So if we have 2 overloads At this point we really need to document this. |
The following code will generate compiler error:
The compiler output:
Because the compiler will first check the
with_temp_file(name: string, body: untyped)
for codewith_temp_file(): ...
, the first parameter is string, but the first argument is untyped code with undefined variablefile
.We can improve the overloaded resolution rule with compare parameter count and argument count before check the argument type. If there is no default parameter value, then the argument count must equals to paramter count. For the previous example, the first with_temp_file takes 2 parameter, and the second with_temp_file take 1 parameter, so we need not to check the first template, and the code will compile successfully. For template with default paramter value, we can still use this rule to filter some template before check parameter type. Suppose the paramter count is
T
, and there is some parameter with default value, suppose numbert
, then the argument count must be betweenT - t
andT
.The text was updated successfully, but these errors were encountered: