nim-lang / RFCs

A repository for your Nim proposals.
137 stars 23 forks source link

Double backtick syntax for verbatim identifiers #484

Closed metagn closed 1 year ago

metagn commented 2 years ago

Abstract

Add a double backtick syntax like ``abcd`` to use the string inside it verbatim as an identifier.

Motivation

Regular backtick/accent expressions are meant for identifier construction, not stropping like in other languages. This means they have weird behavior like `2d` meaning the identifier `2.0` (edit: https://github.com/nim-lang/Nim/issues/11810).

It is unambiguous with existing Nim syntax as the empty accent quote (``) cannot be parsed in current Nim. The syntax is also "ugly" enough that it will only be used in cases where verbosity is absolutely required, meaning it will be less likely to be abused.

Rendering AST generated by macros, wrapper generators etc can use this to more safely deal with identifiers.

Description

Suggested before in:

A negative is it adds yet another feature and complexity to the parser. For this reason I do not love the idea. However it's pretty easy to implement, and it shouldn't affect anything other than the parser considering it can just output AST with kind nkIdent.

This was originally suggested in the context of style-sensitive identifiers. I have no preference regarding this syntax implying style-sensitivity, but I believe any way of doing so would require it to use its own AST kind rather than nkIdent.

Code Examples

var ``a b c``: int # the identifier is "a b c", not "abc" as with single backticks
var ``2d``: int # the identifier is "2d"
var ``__c``: int
var ``a_a-12_f``: int
var ``a:::b``: int
var ``a::b``: int

macro foo =
  let name = ident("a_a-12_f")
  result = quote do:
    var `name`: int
foo() # error: redefinition of a_a-12_f

Backwards Compatibility

Code using this can't be used on older versions, but it should not affect code written in older versions.

Araq commented 2 years ago

Not that I like what I'm about to propose but...

Maybe we should consider to allow string literals for identifiers in declarations and in usages it can be written as ``"abc":


var "super glue": int
echo ``"super glue"
juancarlospaco commented 2 years ago

See also https://github.com/nim-lang/RFCs/issues/428#issuecomment-1242821481

Zectbumo commented 2 years ago

@Araq Would that compile to the same thing as this?:

var `"super glue"`: int
echo `"super glue"`
Araq commented 2 years ago

I suppose so.

xigoi commented 2 years ago

Hmm, since `"a b"` seems to already work, why not just use that?

metagn commented 2 years ago

I'm not sure, for some reason before I thought `"a b"` was the identifier "a b" with quotes. You might be able to use it, but it's kind of janky. You would have to escape the string every time then the parser would have to unescape it etc. I wouldn't want a renderer outputting that. I guess the language is not made for renderers though.

c-blake commented 2 years ago

@xigoi may be onto something here..We'd still need a verbatim mode/ident normalization off switch, of course..

var `"a_b" c "d E"` = 1
echo `"abcd e"`

I don't see a lot of people writing code like that, and I'm not sure that's a positive feature. (I continue to think opt-in to insensitivity with compiler flags and/or maybe imperfect style translating import is a better default than opt-out of insensitivity with verbose quoting.)

Zectbumo commented 1 year ago

Hmm, since `"a b"` seems to already work, why not just use that?

Well, it's what I was getting at.

metagn commented 1 year ago

Closing because not really actionable + I guess `" "` exists, also there is a funnier option of `""" """` that ignores escape sequences

juancarlospaco commented 1 year ago

But then should be documented... 🤔