Skip to content

Style check/remove do: blocks lifted to lambdas #486

@metagn

Description

@metagn

Abstract

There is a behavior in these lines in the compiler, that allow do: blocks without parameter lists (parsed as raw statement lists), to be lifted to lambdas with no parameters (the same as do ():). The proposal is to do one of:

  • Turn this into a style check hint, that is, when --styleCheck is turned on, hint to the programmer that do (): should be used (my preferred solution)
  • Deprecate/remove this behavior, and turn it into a special warning/error

Motivation

No response

Description

This is a weird special case that implies do: and do (): are meant to be the same construct, despite both commonly being used for different purposes. There is already discussion about this "inconsistency", see #264 and nim-lang/Nim#12117.

There is no reason for do: to be ambiguous here, it is not hard to accept that do: and do ...: parse as different things since the visual rule is as simple as "check if there is anything between do and :". Other keywords in the language like of, except, object/enum also have different meanings with different contexts.

nim-lang/Nim#12117 attempted to remove the distinction between do: and do (): by making them all parse as lambdas. I propose embracing the distinction and making do: not ambiguous, thereby making code more clear about what it does.

But, this doesn't have to be forced; the compiler can just complain about it being bad style instead of erroring. This is what I prefer, I consider it more practical. The special case is only a few lines, it doesn't really harm anyone beyond optics.

Post-implementation edit: nim-lang/Nim#13900 and nim-lang/Nim#5963 are bugs with this feature

Code Examples

proc twiceLambda(x: proc()) =
  x()
  x()

twiceLambda do (): echo "a" # fine
twiceLambda do: echo "a" # hint/warning/error: add parentheses to make a lambda

template twiceStmt(x: untyped) =
  x
  x

twiceStmt do: echo "a" # fine
twiceStmt do (): echo "a" # error

Backwards Compatibility

When tested against CI, only one package was affected by this in one line, argparse. The solution is literally just to change do: to do (): in that line.

If this is only a style check, there are obviously no compatibility problems.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions