Has there ever been discussion about Roc potentially having a syntax for special identifier names? Something like Zig's @"you can do anything here"-names?
I've been working on an icalendar-parser library in Zig, and it's pretty nice that names in the icalendar format can be 1:1 translated to Zig identifiers. I was contrasting with some earlier work doing an Html-rendering module in Roc, and having to decide how to map the space of valid HTML attribute names to the space of valid Roc identifiers. You have to think through possibility for these mappings to introduce naming conflicts. It's a bunch of friction that goes away if there's an escape hatch for arbitrary identifier names. If the escape hatch requires extra syntax (like is the case with Zig), I think that discourages people getting overly cute with it.
I think these benefits exist wherever you try to integrate with some other system that uses different naming conventions. A jq-alternative platform like Hannes' describes in #ideas > Roc platform as an alternative for FZF, or Ripgrep will be much simpler and more intuitive if JSON is mapped to Roc values 1:1, without name-conversions.
Anyway, I imagine this has been talked about before, curious if there's already a decision one way or the other!
honestly I'd never thought about it!
obviously the default in most languages is to just use a slightly different name to dodge reserved keywords, e.g. the classic typ or clazz
mapping directly to/from serialized data like JSON is interesting, and something I hadn't considered as part of the tradeoffs for this
i like the Zig syntax and having the power to have arbitrary names quite a bit, but we've never discussed it
it'd be trivial to tokenize and parse something like this
I wonder if it's useful beyond record fields specifically :thinking:
because if it's just for record fields, there's a pretty obvious syntax: allow quoted field names like { "foo": bar } and that's it
and then you access them with rec."foo"
yeah not having map literals makes it easy
I guess record field names wouldn't help with the dsl use case
one simple idea that could work around reserved keywords specifically would be to let you surround them with parens, e.g.
(if) = 5
1 + (if)
all of our keywords are followed by some sort of extra information, so I think this would be unambiguous
looks weird though haha
:thinking: do any of Roc's reserved keywords actually conflict with html or SQL?
we have where but that's only in type annotations, so it can be permitted in expressions
Would that syntax support "breaking" other naming conventions beyond the ban of reserved keywords? Like use of otherwise non-allowed characters or different capitalization styles?
I don't think the parens idea could, although the quoted field names thing could
i think the parens would cause issues at tokenization time
you would really want this to be a uniform unique syntax so that the tokenizer can intern it quickly and unambiguously
maybe backticks like Rust?
backticks for identifier names on the one hand seem like an intuitive and easy to learn design, but on the other hand they would predictably cause unintentionally broken markdown :sweat_smile:
``if`` = 5
if code is in a code block it's fine with the right syntax highlighting
but inline code gets weird for sure
yeah
I guess that would discourage even further using it unnecessarily :laughing:
It's definitely not something I'm going to race to implement, but I think if you want to give it a shot it'll be easy and could still be a v0.1 thing
an argument for having it for all identifiers, not just field names, is that it would let you do all the usual destructuring etc, e.g.
{ `if` } = { `if`: 5, x: 6, y: 7 }
yep
And only the tokenizer needs to be updated
I guess we'd have to determine whether they are only for lower idents or we'd have to determine whether it's an upper or lower ident by looking at the first significant character
i'd probably prefer Type Names not use this :rolling_on_the_floor_laughing:
since uppers never conflict with keywords
I'll try to think of a few more examples where this could be useful, if that's helpful for making for the case beyond just record field names. My intuition is that there's a long tail of APIs with different naming and casing conventions then Roc's where not needing to worry about naming conventions will be nice. And given the expectation that static dispatch will encourage the use of the builder pattern for constructing larger data structures, in my mind that ties record names and function names into the same domain. As in: if you can have a record field "if" and a builder for constructing the record, probably you'll want the function names the builder exposes to match the record field names.
TIL Kotlin supports the backticks syntax for this: https://www.baeldung.com/kotlin/backticks
R also uses backticks this, though I feel like it comes up more often in R’s common use cases than it would in most languages. For example, it’s extremely common for me in R to need to read a CSV where the column names have spaces in them. And for better or worse, R has a lot of magical, dynamically-scoped contexts where you can conveniently refer to the column names as variables without needing to declare them or destructure anything
Last updated: Jun 16 2026 at 16:19 UTC