SE-0275: Allow more characters (like whitespaces and punctuations) for escaped identifiers

-1. I'm against strongly this proposal for several reasons:

  • It makes basic tooling harder to build, because the simple notion of "what's an identifier that can name things in Swift" is no longer simple. GitHub syntax-highlighting var in the var `some var` = 0 example from the proposal is one example. If you double-click on either of the works within the back ticks, there is no editor or tool out there that will properly select the whole identifier. And because back-ticks aren't a balanced set of delimiters, you literally have to scan to the beginning of the source line to determine what is the "identifier".

  • Putting unstructured text within the back-ticks cuts off any future evolution that might put more structured information within back-ticks. For example, providing the ability to name zero-parameter functions or to name the accessors of properties as a function entity, e.g., x.`getter:property` or ``x.zeroParameterMethod(), which cannot be named today. Similarly for subscripts. Some of this was discussed a long time ago, but still seems like a good direction for the language. We shouldn't cut off future directions for a small win.

No. There are two motivating use cases as far as I can tell:

  • Having spaces in the names of test functions. This is a small convenience, and we can probably improve this case in another way.

  • Being able to reference an operator by name, e.g., Int.+` . This one could be addressed by allowing Int.+ in the grammar. It's more discoverable and should be straightforward.

    Doug

36 Likes

I'm with @Douglas_Gregor and a few others on this one, I'm -1.

I've always viewed the back-tick solution as a backup feature that was an ugly but necessary evil for very certain edge cases. This proposal brings it to the forefront as a 1st class language feature where I think a more elegant solution could be found.

I can see the one thing that everyone likes is the ability to do Int.'+' (replace single quotes with back-ticks), and I agree that's a really nice thing to have. But like @Douglas_Gregor said, it's nicer to have it without the back-ticks at all. I can't comment on the implementation side, but from a user point of view it's discoverable and makes sense whilst also feeling swifty.

I have no experience of using test cases with spaces like the example, but while I see the appeal at the call site the declaration itself is very convoluted and difficult to parse when skimming through code. I think a better solution is out there for this, possibly something along the property wrapper lines but for functions, but for me back-ticks solution isn't it.

I like the desire behind the proposal, but not the solution.

12 Likes

-1

a) Snake case is perfectly fine for the case with the test-method names.
b) Back-ticks are okay if unavoidable for edge cases. Better is without.
c) Referencing operators can be solved separately.
+) Back-ticks hurt readability and are a complication.

9 Likes

-1. I don't believe the proposal as written would be a good step forward for Swift.

Aspects of it are, and I think improvements can be made here, I just am not in favor of this specific proposal.

From a technical position, as far as I can tell, the proposal cannot be implemented. It suggests:

This proposal wants to extend the current grammar for every escaped identifier (properties, methods, types etc...) by allowing every Unicode scalar.

...but of course, backtick shouldn't be allowed inside the backticks :-).

My more general concern is that this is taking a very important grammar production and throwing the door way open, completely occupying the space that may be important for other reasons. Taking this proposal would mean that it is impossible to introduce a grammar into the backquotes to refer to aggregate names (e.g. the getter on a decl), for example. It isn't clear that we would want to do that, but that's the thing about the future: it is hard to predict.

I would be more favorable of specific limited expansions, e.g. if it were important to allow a horizontal space in backticks then we could consider that. OTOH, I consider that to have very marginal value over using underscore: I don't see how:

func `foo bar`() {
}

is better than:

func foo_bar() {
}

Finally, if such an expansion of the grammar takes place, we should incorporate something about this into the Swift API Naming Guidelines.

No.

Detailed review.

-Chris

18 Likes

-1

This seems to add support for something which generally increases complexity of the language for a feature which seems can be accommodate in other ways.

No. The strongest motivation seems to be testing usages. This is a reasonable request, but it seems better as associated "metadata".

No.

Yes, testing with it style declarations in JavaScript offer similar level of self-documenting code with string metadata associated with the function. This feels like trying to augment the syntax for something similar which doesn't seem necessary to support the functionality.

A quick read

5 Likes

Hi Chris, thanks for the feedback, I want to share a correction about this.

Backtick are indeed not allowed, in fact are specified in the proposal, in the grammar details section (I used the Unicode value, maybe that’s why you may have missed it, anyway I will take it as an amend for future proposals).
It is then, very important to clarify that the proposal can be implemented and is actually already implemented in a PR attached to the proposal together with a working toolchain.

Hi @Douglas_Gregor thank you very much for the review!

Even if this topic comes from 5 years ago, I do agree with you that it could be interesting and good for Swift.
Without entering into the detail of a different proposal, I would like to ask you (and @Chris_Lattner3 since he raised a similar lost opportunity) why we should necessary consider that this proposal completely cut off something like your suggestions. I do understand that it should be considered a "source breaking change", but it would also be true that it would be kind of unlikely to happen, i.e.: in order to conflict with getter:property we would need to define a func/property named that way, do you feel that we should completely avoid that, no matter if it may not happen often or, even, at all?

Github syntax-highlighting is unfortunately already broken with the current support of backtick, in fact having something like var `class` won't be correctly highlighted (as it is considered as keyword), while this should not be read as: it is already bad, so it is not important. I believe that extending support and therefore increase usage of the back-tick syntax may actually help prioritize and improve syntax-highlighting.
It is worth to mention, to make it clear for all the readers, that obviously this won't apply to Xcode, which will natively support, in case the proposal will get accepted.

Thanks again,

I second this. I think this proposal should be updated a few more times.

It also doesn't explain very well that ` is still not part of the identifier. Should the escaped identifier without ` be a valid identifier, it will be treated as that identifier, and should the escaped identifier without ` be a valid operator, it will be treated as that operator. This is an important part of the design that we probably want to make clear that it is not changing.

I also agree with this. And to add that we might accidentally include many more characters that could be annoying to work with. Whitelisting might be better than blacklisting in this case.

1 Like

-1. I think the problem that this proposal aims to solve is not on the language side, but rather on the testing framework side, and therefore should be solved by different means.

If we did go with the language-level change, I'd rather prefer this issue to be addressed using custom attributes:

@TestDescription("validation should succeed when input is less then ten")
func testValidation() {
    // ...
}

Besides, I argee with @Douglas_Gregor regarding syntax highlighting, which will be broken. It is already hard enough to properly highlight Swift code (even today GitHub fails to do it in some cases, e. g. with contextual keywords).

I believe the problem described in the Motivation section is not broad enough to be solved with such a radical syntax change. Like people already mentioned, there's nothing wrong with using underscores instead of whitespaces. I personally have never found a need to use whitespaces in my testing methods, and I'm quite an active XCTest user.

IMO, it does not.

I have not.

I've read through the text of the proposal.

5 Likes

Thank everyone for the important feedbacks you all have been sharing.
I opened a PR to amend some changes in order to add clarity on the doubts that have been raised during these days.
You can find the full diff here: https://github.com/apple/swift-evolution/pull/1113/files

1 Like

There's some interesting prior art here in SQL; the language standard allows identifiers to be arbitrarily named—including whitespace—requiring double-quotes around identifiers and single-quotes around string literals. Engines tend to allow the omission of double quotes for identifiers that match [a-zA-Z0-9]+ (as this proposal must imply for source compatibility), and some engines also allow double quoted string literals when there is no ambiguity.

In my experience this permissiveness (and complexity—the rules for how a token may be interpreted is now three levels deep!) adds far more confusion than benefit and I feel like it is not in Swift's best interests to support relatively arbitrary symbol naming.

5 Likes

I actually like the proposal less now with the amendments. This is primarily due to the Alternatives considered section now having references to off hand suggestions from people in this thread that haven't been fully discussed and explored but the proposal dismisses them entirely.

The additional examples also make me realise that this won't just be used in a few places, but could be used everywhere which will clutter the language into an ugly mess. Granted my opinion is subjective rather than objective, but for this proposal its something I feel quite strongly about. I don't want to constantly wonder if something required back-ticks or not (as demonstrated in the case examples), I just want to use a predictable language that is all accessible in the same consistent manner.

2 Likes

-1

The proposal is too big of a hammer for this nail. I agree with the above statements by Douglas. I don’t think the usecases warrant a chance in swift.

I would be more in favor of a smaller hammer that would introduce a matrix of supported cases that we can then as a community agree upon. One usecase that is important to me is identifies that start with numbers.

5 Likes

That's not a fair characterization, in my opinion. The additions that the author made to Alternatives Considered and Future Directions—a @test attribute, discussion of Unicode normalization, and a possible way of escaping backticks in a backtick-escaped identifier, the effects on a future runtime type lookup API—were all discussed in the original pitch thread and weren't just off-hand suggestions that came up during the review.

As a meta discussion point, this is unfortunately an example of the concern I had in my review of this proposal up-thread. I wish the original proposal text had captured the good amount of discussion in the pitch thread that fleshed out more details and additional motivating use cases so that it would be (IMO) a more accurate representation of what the proposed change is.

There have been a number of reviewers in this thread who have said that the proposal's "only motivating use case" was for test naming. While I don't agree that's the case and mentioned others from the pitch thread in my own review, I also can't disagree that that's a valid takeaway from a proposal review standpoint for someone who didn't follow the pitch thread, because what they're reviewing is the proposal text that was posted here, not all of the preceding context/discussion.

7 Likes

I just want to echo the last two paragraphs of @allevato’s post above.

1 Like

As it stands, the proposal permits too many new kinds of characters for escaped identifiers for me to +1 it.

-1

I find this point debatable.

Yes, this proposal fits the feel and direction of Swift, however poorly. It does outline and address some apparent deficiencies that restrict identifier naming, e.g. naming enum cases like .200.

Never have I ever used a programming language that permits whitespace in identifiers.

I read the proposal and followed the discussion in this thread.

1 Like

Proposal rejected

The review of SE-0275: Allow more characters (like whitespaces and punctuations) for escaped identifiers ran from January 13 through January 20. The core team has decided to reject this proposal. Community reaction was mixed, and many of the people both supporting and rejecting the idea had concerns about the breadth of the set of characters this allows. Allowing more characters in identifiers would also add complexity to tooling, including syntax highlighting, IDEs, and runtime reflection libraries, which would need to be able to recognize quoted identifiers, know when identifiers would need to be quoted for presentation purposes, and potentially need to implement more elaborate parsing and escaping rules to handle these generalized identifiers. In the core team's judgment, this added demand on tooling is not justified by the amount of utility provided by the proposal. Of the use cases that came up in the pitch, proposal, and review discussion:

  • One proposed use was to allow test functions to have self-descriptive natural language names, as in func `test that two plus two equals four`() . The core team feels that this use case could be better handled by test library design that allowed strings to be associated with test cases, rather than try to encode that information entirely in symbol names.
  • This feature could also be used to enable libraries to more directly encode domain-specific names that are not currently valid Swift identifiers, such as status codes which begin with numbers like HTTPStatus.`404`, naming conventions that use normally-reserved symbols like SFSymbols.`10.circle`, or names from other languages Swift may interoperate with that have different valid identifier character sets like Forth.`FM/MOD`. This use case is more in line with the original intent of the backtick identifier feature, which was to allow for interop with libraries from C/ObjC/C++ that use names that would normally be reserved in Swift. However, the core team would like to see more concrete work done on libraries that would benefit from this functionality, to better gauge whether it is really essential or merely nice-to-have, and whether allowing a more restricted character set could achieve the desired results with less tooling complexity burden.
  • The proposal also offers the syntax Foo.`+` as a way to spell qualified references to operators. The core team believes this is an important gap in the language to fill. However, the backtick syntax in its current form is strongly associated with removing "magic" from keywords, and in association with operator tokens, there is a potential for confusion as to whether + is the same as the operator + or a regular identifier made to be named + . Furthermore, there are additional aspects of operator naming that need to be addressed in order to fully solve the problem; particularly, there would ideally be a way to disambiguate the prefix , postfix , and infix forms of an operator without relying on type context to do so. The core team thinks that the subject of operator references deserves a design exploration of its own, with its own pitch and proposal.

Thanks to @adellibovi for proposing and implementing this feature, and thanks to everybody who participated in the review!

25 Likes

Fair enough, thanks for discussing this!

I think Swift needs a broader strategy for improving tests. This change would have addressed one of the pain points (the desire for plain-English descriptions of tests), but not others, like:

  1. Automated test discovery on platforms without an ObjC runtime
  2. Parameterized tests, or more generally, procedurally generated tests. E.g. if you want to test 10 similar things, you can use a loop, but:
    1. There's still only one test, so you can't rerun a single "run" of the loop body as its own independent test
    2. Since there's only one test, a test failure doesn't tell you precisely which iteration of the loop failed.
  3. There's no way to mark your own function to "act like a test helper function" ( like XCTAssertEqual(_:_:)).
    • Kinda hard to explain, but bear with me. When you call XCTAssertEqual with unequal arguments, Xcode shows the callsite of XCTAssertEqual as being the "problem spot", not the line of code inside of the implementation of XCTAssertEqual that actually raises the error/signal/whatever. Contrast that with your own functions. If you tried to make a helper function to simulate a parameterized test (you make N test cases, each calling this helper function with a different set of parameters, to emulate 1 test case with N parameter sets), and you hit a broken assertion, Xcode highlights the failing XCTAssert* within the helper's implementation. There's no way to get Xcode to treat the helper function opaquely like it does with XCTAssert*, to make it show the callsite as the "problem spot", rather than a part of its implementation.

I think these issues could be better addressed by rethinking how tests are implemented, through some combination of better reflection (that works across platforms), hygienic macros, or some other novel approach.

I think what you want here is to take file: StaticString = #file, line: UInt = #line arguments in the helper and forward them to calls to the underlying XCT methods. This will cause Xcode to report the error at the site of the call to the helper instead of inside the helper implementation.

8 Likes

Omg, I didn't know about that. It's boiler-platey, but decent!

2 Likes
Terms of Service

Privacy Policy

Cookie Policy