Stream: ideas

Topic: Syntax for arbitrary identifier names


view this post on Zulip Jasper Woudenberg (Jun 08 2025 at 11:09):

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!

view this post on Zulip Richard Feldman (Jun 08 2025 at 13:49):

honestly I'd never thought about it!

view this post on Zulip Richard Feldman (Jun 08 2025 at 13:52):

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

view this post on Zulip Richard Feldman (Jun 08 2025 at 13:53):

mapping directly to/from serialized data like JSON is interesting, and something I hadn't considered as part of the tradeoffs for this

view this post on Zulip Anthony Bullard (Jun 08 2025 at 13:53):

i like the Zig syntax and having the power to have arbitrary names quite a bit, but we've never discussed it

view this post on Zulip Anthony Bullard (Jun 08 2025 at 13:54):

it'd be trivial to tokenize and parse something like this

view this post on Zulip Richard Feldman (Jun 08 2025 at 13:54):

I wonder if it's useful beyond record fields specifically :thinking:

view this post on Zulip Richard Feldman (Jun 08 2025 at 13:55):

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

view this post on Zulip Richard Feldman (Jun 08 2025 at 13:55):

and then you access them with rec."foo"

view this post on Zulip Anthony Bullard (Jun 08 2025 at 13:55):

yeah not having map literals makes it easy

view this post on Zulip Richard Feldman (Jun 08 2025 at 13:59):

I guess record field names wouldn't help with the dsl use case

view this post on Zulip Richard Feldman (Jun 08 2025 at 14:04):

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

view this post on Zulip Richard Feldman (Jun 08 2025 at 14:04):

looks weird though haha

view this post on Zulip Richard Feldman (Jun 08 2025 at 14:07):

:thinking: do any of Roc's reserved keywords actually conflict with html or SQL?

view this post on Zulip Richard Feldman (Jun 08 2025 at 14:07):

we have where but that's only in type annotations, so it can be permitted in expressions

view this post on Zulip Jasper Woudenberg (Jun 08 2025 at 14:09):

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?

view this post on Zulip Richard Feldman (Jun 08 2025 at 14:13):

I don't think the parens idea could, although the quoted field names thing could

view this post on Zulip Anthony Bullard (Jun 08 2025 at 14:14):

i think the parens would cause issues at tokenization time

view this post on Zulip Anthony Bullard (Jun 08 2025 at 14:15):

you would really want this to be a uniform unique syntax so that the tokenizer can intern it quickly and unambiguously

view this post on Zulip Anthony Bullard (Jun 08 2025 at 14:15):

maybe backticks like Rust?

view this post on Zulip Richard Feldman (Jun 08 2025 at 14:17):

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:

view this post on Zulip Anthony Bullard (Jun 08 2025 at 14:18):

``if`` = 5

view this post on Zulip Anthony Bullard (Jun 08 2025 at 14:19):

if code is in a code block it's fine with the right syntax highlighting

view this post on Zulip Anthony Bullard (Jun 08 2025 at 14:19):

but inline code gets weird for sure

view this post on Zulip Richard Feldman (Jun 08 2025 at 14:22):

yeah

view this post on Zulip Richard Feldman (Jun 08 2025 at 14:25):

I guess that would discourage even further using it unnecessarily :laughing:

view this post on Zulip Anthony Bullard (Jun 08 2025 at 14:26):

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

view this post on Zulip Richard Feldman (Jun 08 2025 at 14:27):

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 }

view this post on Zulip Anthony Bullard (Jun 08 2025 at 14:29):

yep

view this post on Zulip Anthony Bullard (Jun 08 2025 at 14:29):

And only the tokenizer needs to be updated

view this post on Zulip Anthony Bullard (Jun 08 2025 at 14:30):

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

view this post on Zulip Anthony Bullard (Jun 08 2025 at 14:31):

i'd probably prefer Type Names not use this :rolling_on_the_floor_laughing:

view this post on Zulip Anthony Bullard (Jun 08 2025 at 14:32):

since uppers never conflict with keywords

view this post on Zulip Jasper Woudenberg (Jun 08 2025 at 15:20):

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.

view this post on Zulip Richard Feldman (Aug 10 2025 at 20:53):

TIL Kotlin supports the backticks syntax for this: https://www.baeldung.com/kotlin/backticks

view this post on Zulip Ajai Nelson (Aug 11 2025 at 07:59):

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