-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
func
doesn't check for side effects in proc parameters
#16303
Comments
IMO the current behavior is both the correct and the useful one, the side effect only happens via a parameter which is declared proc. The manual just needs to be clarify that side effects are allowed via proc parameters. |
Could it also enforce that a proc parameter does not have side effects? |
that would make |
Do you mean, "add Because if you write: it produces:
|
|
And here's an example explaining why it's safe to have a when true:
func callCb(cb: proc(): int): int = result = cb()
proc mycb1(): int = 1
proc mycb2(): int = (echo "ok"; 1)
func bar(): int =
# result = callCb(mycb1) # ok: no error generated here
result = callCb(mycb2) # ok: correctly reports Error: 'bar' can have side effects
echo (bar(),)
|
This commit changes the funcs that take a `proc` parameter back to procs. This reverts some of commit 6f57eba: sequtils.nim: Use `func` (nim-lang#16293) See also: - nim-lang#16303 - nim-lang#16304
Works as the spec says it does, the spec is overly brief though. See for example: proc echoInt(n: int) =
echo n
func foo(n: int, bar: proc(x: int)) =
bar(n)
func more =
foo(2, echoInt) # error: 'more' can have side effects
more() |
the spec doesn't match the implementation, as I explained above.
That's incorrect, see below example: when true:
func foo(bar: proc(): int): int = bar()
var count = 0
proc fn1(): int = 1
proc fn2(): int = (count.inc; count)
func fun1() = discard foo(fn1) # ok
# func fun2() = discard foo(fn2) # Error: 'fun2' can have side effects
# with callbacks, the compiler is conservative, ie that bar will have side effects
var foo1: type(foo) = foo
func main() =
discard foo(fn1) # ok
# discard foo1(fn1) # now this errors
main() This time, the implementation is the correct, sane, most useful behavior (see #16303 (comment)), the spec is overly restrictive. It's easy to correct and I can volunteer a PR to fix it, along those lines: Side effects in a < insert above example >. If none of its parameters have the type var T or out T or ref T or ptr T or proc without In the new spec,
|
I'm refering to this section of the spec:
Every effect is subject to these rules, including the write tracking effect. Unfortunately the spec doesn't say that. So yeah, PRs are welcome. |
A decision must be made, this is becoming edit war via pull requests |
I think that's a bit too strong. There's just 2 open PRs, they're both mine, and they're simply:
There's no rush, except that people on But at this point I'd like to make a PR that does a safe first pass that changes all procs tagged with For procs that aren't tagged with |
is not about the amounts, is about wasted effort, that can be put into fixing actual bugs. |
Well, in any case it's easy to just keep a
Sure. But this discussion would've happened eventually, and we can always just revert any questionable commit. So hopefully most of the wasted effort is mine :) |
This commit changes the funcs that take a `proc` parameter back to procs. This reverts some of commit 6f57eba: sequtils.nim: Use `func` (nim-lang#16293) See also: - nim-lang#16303 - nim-lang#16304
This commit changes the funcs that take a `proc` parameter back to procs. This reverts some of commit 6f57eba: sequtils.nim: Use `func` (nim-lang#16293) See also: - nim-lang#16303 - nim-lang#16304
This commit changes the funcs that take a `proc` parameter back to procs. This reverts some of commit 6f57eba: sequtils.nim: Use `func` (nim-lang#16293) See also: - nim-lang#16303 - nim-lang#16304
What's the intended behaviour here?
Example
See: https://play.nim-lang.org/#ix=2HiM
Current Output
which also occurs if you compile with
--experimental:strictFuncs
.Expected Output
Either
in which case, I think the manual could be a little clearer, or:
which is what happens if you call
echoInt
inside thefunc
more directly:An error is produced if we write:
Additional Information
This behaviour occurs with
devel
and all Nim versions going back to v0.18.0, which introducedfunc
.The manual contains:
Nim/doc/manual.rst
Lines 6155 to 6161 in 9ce2f87
The procedural type is internally a pointer to a procedure, but I don't know if it's supposed to be covered by "
var T
orout T
or
ref T
orptr T
".The experimental manual says this about
strictFuncs
:Nim/doc/manual_experimental.rst
Lines 1785 to 1790 in 9ce2f87
The text was updated successfully, but these errors were encountered: