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

RFC: {.disabled.} pragma #145

Open
timotheecour opened this issue Apr 28, 2020 · 0 comments
Open

RFC: {.disabled.} pragma #145

timotheecour opened this issue Apr 28, 2020 · 0 comments

Comments

@timotheecour
Copy link
Owner

timotheecour commented Apr 28, 2020

summary:

semantics of proc foo {.disabled.} = ...

  • declared(foo) should return false (unless declared(foo) was already true because of another symbol with same name)
  • a symbol foo {.disabled.} should not participate symbol lookup nor in overload resolution unless there is an error; in particular, it cannot cause a redefinition error

The only semantic difference between proc foo {.disabled.} = ... and when false: proc foo = ... is that it gives better error messages when lookup/sigmatch fails:

  • when lookup for an ident "foo" fails, instead of Error: undeclared identifier: 'foo' we show: Error: usage of 'foo' is {.disabled.} at mymodule.nim(12,1)
  • when sigmatch for overloaded "foo" fails, we add to the list of candidates in expected one of ... list the disabled symbol (and show the {.disabled.} pragma)

other use cases of {.disabled}

  • replace {.error.} by {.disabled.} in code disabled for for custom targets (js,nimscript), so we avoid import os + use of existsDir/dirExists/existsFile/fileExists/findExe in config.nims causes "ambiguous call' error nim-lang/Nim#14142 while keeping informative errors

  • use it inside the {.since: (1, 3).} pragma for nicer error messages without changing semantics of since; so now you'll get more informative errors like:
    `newSymbolX` is available starting 1.3.1, not 1.2.0

  • with when cond: {.push disabled}, we can conditionally disable all the remainder of the code in the same scope without having to re-indent under when not cond; this somewhat related to D's __EOF__ special token except it's during semantic, and is more useful (eg: scoped)

  • in particular, when used at module-level, this allows conditionally disabling all remainder of a module, which is needed for an RFC I'm preparing that will allow introducing user defined self-contained module metadata, and reduce the need for separate foo.nims files, magic testament spec blocks, magic exclusions in kochdocs, magic comments indicating this is only an include file etc. More on this soon.

  • (optional feature): disabled inside push/pop section
    this reduces the need for having to re-indent a whole section, eg:

# this line is not disabled for js
when defined(js): {.push("mylabel"): disabled.}
# this line is disabled for js
proc fun1(f: File) = ...
proc fun2() = ...
{.pop("mylabel").} # this pops what was pushed with the same label (mylabel); this prevents pop from being disabled! it's ignored if no matching push with the same label.
# this line is not disabled for js

implementation

seems straightforward

why not use {.error.} instead for that?

semantics are different, {.error} procs participate in overload resolution and declared(foo) is true

why not change semantics of {.error.} to be like disabled instead?

that'd be a breaking change (eg: declared(foo) would turn from true to false), and IMO {.error} fullfils a different role than {.disabled}

why not use template disabled(body): untyped = discard instead?

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

1 participant