-
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
transform static: stmt
and const foo = expr
into immediately invoked lambas => fixes many bugs
#276
transform static: stmt
and const foo = expr
into immediately invoked lambas => fixes many bugs
#276
Comments
It's good that it "would fix many bugs" but I don't see how in principle that makes the language simpler. Lambdas have a complex setup for capturing surrounding variables and that complexity is intristic whereas the bugs might just be implementation artifacts which we can fix one after another. |
It could be that capture is exactly what's needed here to avoid existing scoping bugs, and that capturing is much less buggy in the language than const/static blocks, so in the meantime we can avoid all those issues which bite us a lot in various forms. Would a tentative PR be accepted (not sure if I have time now but anyone else could too) ? |
A PR would be interesting as it would tell us which different problems this solution produces. ;-) |
I had a look. All issues above can be fixed today by removing the check in if s.kind in {skVar, skTemp, skLet, skParam, skResult} and
not s.isOwnedBy(c.prc.sym) and s.owner != c.module and c.mode != emRepl:
cannotEval(c, n) However, it would allow some invalid code to passthrough. Examples of accept invalid in this case: In my opinion the correct fix would be to reject invalid code in the sempass and remove check in vmgen. This example should not pass the sempass: proc test =
var i = 0
const TEST = block:
let j = 2
i + j # rejected in sempass not in vm codegen |
@cooldome your suggestion would only fix example 1 above, and would not help with example 2, 3, 4, 5 (i just checked) Whereas the immediately invoked lambda would fix all examples 1,2,3,4,5 and possibly many other issues with static/const (note: I've just identified yet another issue that'd be fixed by this trick: nim-lang/Nim#13887) |
see also nim-lang/Nim#21351 |
Neither should this though, the variable still needs to track where it was defined: proc test =
const TEST = block:
let i = 1
const j = i + 1 # error
j |
fixes nim-lang#8758, fixes nim-lang#10828, fixes nim-lang#12172, fixes nim-lang#21610, fixes nim-lang#23803, refs nim-lang/RFCs#276
fixes nim-lang#8758, fixes nim-lang#10828, fixes nim-lang#12172, fixes nim-lang#21610, fixes nim-lang#23803, refs nim-lang/RFCs#276
This would solve a number of nasty scoping issues involving
static
andconst
.the intuitiion is that block variable scoping at CT is buggy (and difficult), so we can instead reuse proc scoping via immediately invoked lambas, which offer the same semantics.
This would be done by a simple compiler transform.
example 1: would fix nim-lang/Nim#12172 (+ dups nim-lang/Nim#13795 nim-lang/Nim#14192)
this is a common bug hidden under many disguises eg see duplicates involving templates, toSeq etc
=> works:
example 2: would fix nim-lang/Nim#10938
=> works:
example 3: would fix nim-lang/Nim#13918
=> works:
example 4: would fix nim-lang/Nim#13312
=> works:
EDIT: example 5: would fix nim-lang/Nim#13887
Example 1 from nim-lang/Nim#13887 adapted to use immediately invoked lambas
ditto for nim-lang/Nim#13887 (comment)
ditto with example 3 in that issue:
ditto with example 2 in that issue:
note
I had originally proposed here: nim-lang/Nim#10938 (comment) but it was burried inside a comment, and I'm now seeing that it solves many other long standing bugs
The text was updated successfully, but these errors were encountered: