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

DRY forward declarations #163

Closed
timotheecour opened this issue Aug 23, 2019 · 6 comments
Closed

DRY forward declarations #163

timotheecour opened this issue Aug 23, 2019 · 6 comments

Comments

@timotheecour
Copy link
Member

timotheecour commented Aug 23, 2019

before RFC

proc fun*[T](a: T, b: string, c = myInit(32)): tuple[int, string] {.gcsafe, noSideEffect.}
# some lines below...
proc fun*[T](a: T, b: string = myInit(32)): tuple[int, string] {.gcsafe, noSideEffect.} = (12, "bar")

after RFC

allow this:

# case1: fun is overloaded
proc fun*[T](a: T, b: string, c = myInit(32)): tuple[int, string] {.gcsafe, noSideEffect.} as foo
# some lines below...
define(foo) = (12, "bar")

# case2: fun is not overloaded, a simpler syntax can optionally be used:
proc fun*[T](a: T, b: string, c = myInit(32)): tuple[int, string] {.gcsafe, noSideEffect.}
# some lines below...
define(fun) = (12, "bar")
  • the identifier foo must be be unique in a given scope (overloads must use different identifiers, eg: as foo1, as foo2) using the usual symbol lookup rules; it shall resolve to an identifier pointing to a PSym that must be a forward declaration

Note that current rules are buggy: nim incorrectly accepts this code despite exportc mismatch; there are similar issues.

proc fun*(a: int): string {.exportc: "boo1".}
proc fun*(a: int): string {.exportc: "boo2".} = discard

note: yes we can improve --experimental:codeReordering to avoid need for forward declarations but the fact is that forward declarations are still needed, and quite often so.

benefits

avoid common pitfalls due to lack of DRY-ness of forward declarations, eg pragmas, default params, types; especially when these change and we have to remember to change both fwd declaration and definition

difficulty to implement:

low

@Araq
Copy link
Member

Araq commented Aug 23, 2019

Well the bugs that are left in the "pragma unification" logic would need to be fixed anyway and this solution cannot work with overloaded procs.

-1 from me, simply yet another thing others have to learn.

@timotheecour
Copy link
Member Author

timotheecour commented Aug 23, 2019

this solution cannot work with overloaded procs.

yes it can, that's the whole point of the as in the declaration that I mentioned that in top post.

proc fun*(a: A, b: string, c = myInit(32)): tuple[int, string] {.gcsafe, noSideEffect.} as fun1
proc fun*(a: B): string as fun2
# some lines below...
define(foo1) = (12, "bar")
define(foo2) = discard

it's simpler (for humans but also for compiler) to find matching declaration via a non-overloadable identifier (fun1 , fun2 etc) than via the parameter matching, which is subject to aliasing, and flexibility wrt whether optional args are specified or not:

proc fun(z: tuple[a: int, b: float], u = 12, v = 13): cint
proc bar() = echo fun((23, 3.3))
type T = tuple[a: int, b: float]
# definition matching declaration but with very different looking signature:
# v doesn't specify its optional value here; return type is int32 instead of cint, tuple is represented as T
proc fun(z: T, u = 12, v: int): int32 = 23
bar()

this is especially true when definition/declaration are split in different files (eg compiler/sem.nim)
In the case of a fwd declaration for for a proc that has no other overloaded forward declaration, the as bar can be omitted anyways.

@Araq
Copy link
Member

Araq commented Aug 23, 2019

Ok, my bad, I skimmed too much. :-)

@Clyybber
Copy link

This may be DRY, but code written with this approach is going to be a lot harder to understand IMO, since it's really inconvinient to have a proc without a signature (have to constantly scroll to check args) and the approach taken for overloads requires one to remember all those aliases.
IMO we should strive to eliminate the need for forward declarations as much as possible instead.

@disruptek
Copy link

This'd be really unpleasant for tooling. 👎

@Araq
Copy link
Member

Araq commented Oct 28, 2020

After IC, we will finally tackle the problem wrt forward declarations and cyclic imports.

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

No branches or pull requests

4 participants